View Issue Details

IDProjectCategoryView StatusLast Update
00012711003.1(2008)/Issue 7System Interfacespublic2022-07-14 15:36
Reporterscottcheloha Assigned Toajosey  
PrioritynormalSeverityEditorialTypeEnhancement Request
Status ClosedResolutionRejected 
NameScott Cheloha
Organization
User Reference
Sectionclock_nanosleep()
Page Number(where is the page number in the HTML version?)
Line Number(where is the line number in the HTML version?)
Interp Status---
Final Accepted Text
Summary0001271: clock_nanosleep() TIMER_ABSTIME: if rmtp is non-NULL, set it to clock_id's time value when returning.
DescriptionAssuming clock_id is a valid and supported clock, if TIMER_ABSTIME is set and rmtp is non-NULL the time value of clock_id's clock at wakeup should be written to rmtp upon return from clock_nanosleep().

Why?

First, this behavior is intuitive. When TIMER_ABSTIME is unset the remaining time for the sleep is written out to rmtp upon return. If TIMER_ABSTIME is set the analogous behavior would be to write the absolute time for the given clock to rmtp, no?

Second, this behavior is useful. Consider an event loop: in an event-driven application where work is performed at particular times the application must *always* read the clock when it wakes up. Even if there is an error, assuming the process isn't terminated the application is eventually going to read the clock. With the current time in hand the application can then decide what to do: either run the events that are ready or go back to sleep.

Portable applications cannot assume the current time in the TIMER_ABSTIME case if clock_nanosleep() returns 0 because the wakeup latency is not defined by the specification. Portable applications will always need to get the current time when they wake up. This is particularly true in the CLOCK_REALTIME case: discontinuous time jumps are permitted by the standard and clock_nanosleep() has defined behavior in that case.

Given that you *always* want to know the current time on clock_id's clock when you wake up, why not just write it out to the spare timespec we have available in the argument list currently serving no purpose?

For implementations using a kernel you save a system call. This means avoiding a potentially costly trip back to the kernel, a useful property for realtime applications.

As for implementations on systems without a kernel, or implementations in library code, in order to compute the remaining time in in the non-TIMER_ABSTIME case that code already needs to have a way to retrieve the current time. So in the TIMER_ABSTIME case those implementations can simply write that value to rmtp.

Kernel or no kernel, little additional code is required of any currently conforming implementation to provide this feature.

The sole potential dealbreaker is that the current specification mandates that rmtp not be modified in the TIMER_ABSTIME case. If there are applications mixing relative and absolute sleeps they may break if this new behavior is enabled. But I think the likelihood of practical code depending upon that behavior is extremely small. Practical event loops are not written with a mix of relative and absolute sleeps.

Of course, if the potential for breaking existing applications is unacceptable a new flag could be introduced that, if set, enabled this new behavior. Possible names for the flag's symbol include "TIMER_NOW", "TIMER_UPDATE", or "TIMER_GET". When set in flags along with TIMER_ABSTIME, if the the rmtp argument is non-NULL, the implementation should write the current time value of clock_id's clock to the timespec represented by rmtp on wakeup. Behavior would be undefined if the new flag were set without TIMER_ABSTIME.

To enable the new behavior, code would then look something like this:

struct timespec deadline, now;
int status;

for (;;) {
    get_next_deadline(&deadline);
    status = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME|TIMER_GET, &deadline, &now);
    if (status == -1) {
        /* handle error */
    }
    if (deadline.tv_sec > now.tv_sec ||
        (deadline.tv_sec == now.tv_sec && deadline.tv_nsec >= now.tv_nsec)) {
        /* handle deadline */
    }
}
Desired ActionWithout a new flag, the change is relatively simple.

Update the clock_nanosleep() page. In particular, the RETURN VALUE section's second paragraph should be updated.

> If the clock_nanosleep() function returns because it has been interrupted by a signal,
> it shall return the corresponding error value.
> For the relative clock_nanosleep() function,
> if the rmtp argument is non-NULL,
> the timespec structure referenced by it shall be updated to contain the amount of time
> remaining in the interval (the requested time minus the time actually slept).
> If the rmtp argument is NULL,
> the remaining time is not returned.
> The rqtp and rmtp arguments can point to the same object.
> The absolute clock_nanosleep() function has no effect on the structure referenced by rmtp.

becomes

> If the clock_nanosleep() function returns because it has been interrupted by a signal,
> it shall return the corresponding error value.
> For the relative clock_nanosleep() function,
> if the rmtp argument is non-NULL,
> the timespec structure referenced by it shall be updated to contain the amount of time
> remaining in the interval (the requested time minus the time actually slept).
> For the absolute clock_nanosleep() function,
> if the rmtp argument is non-NULL,
> the timespec structure referenced by it shall be updated to contain the time value of the
> clock specified by clock_id.
> For both the relative and absolute clock_nanosleep() functions,
> if the rmtp argument is NULL,
> it is ignored.
> The rqtp and rmtp arguments can point to the same object.

--

If people find the flag preferable the change would be more involved.

Update the RETURN VALUES section on the clock_nanosleep() page. The second paragraph would need to be modified:

> If the clock_nanosleep() function returns because it has been interrupted by a signal,
> it shall return the corresponding error value.
> For the relative clock_nanosleep() function,
> if the rmtp argument is non-NULL,
> the timespec structure referenced by it shall be updated to contain the amount of time
> remaining in the interval (the requested time minus the time actually slept).
> The rqtp and rmtp arguments can point to the same object.
> The absolute clock_nanosleep() function has no effect on the structure referenced by rmtp.

should changed to something akin to the following:

> If the clock_nanosleep() function returns because it has been interrupted by a signal,
> it shall return the corresponding error value.
>
> For the relative clock_nanosleep() function,
> if the rmtp argument is non-NULL,
> the timespec structure referenced by it shall be updated to contain the amount of time
> remaining in the interval (the requested time minus the time actually slept).
> If the rmtp argument is NULL,
> the remaining time is not returned.
>
> For the absolute clock_nanosleep() function,
> if the TIMER_GET flag is set and the rmtp argument is non-NULL,
> the timespec structure referenced by rmtp shall be updated to contain the time value of the
> clock specified by clock_id.
> If TIMER_GET flag is unset,
> or the rmtp argument is NULL,
> the time value of the clock specified by clock_id is not returned.
>
> Regardless of the value of flags, the rqtp and rmtp arguments can point to the same object.
TagsNo tags attached.

Activities

eblake

2019-08-15 15:51

manager   bugnote:0004522

Last edited: 2019-08-15 15:53

The idea was discussed in the 2019-08-15 meeting; consensus was that a new flag may have merit, but we would need a reference implementation. Is there a link pointing to a library where this has been implemented already, or to a mailing list discussion where an existing implementation has expressed interest in taking this up first, before standardizing anything?

A new flag has further benefits - the new behavior becomes introspectible (if the flag exists, you can opt in to using it), so that is better than changing the default behavior.

I fired off a question to glibc to see if they want to become a reference implementation: https://sourceware.org/ml/libc-alpha/2019-08/msg00394.html

Don Cragun

2022-07-14 15:36

manager   bugnote:0005887

While we agree that this sounds like a reasonable request (using a new flag), without a reference implementation there isn't anything for us to standardize at this time. The discussion referenced in 0001271:0004522 raises several questions that have not been answered in the last three years. This bug is therefore rejected. If an implementation is created, please file a new bug with details of the changes and a pointer to a reference implementation.

Issue History

Date Modified Username Field Change
2019-07-20 16:50 scottcheloha New Issue
2019-07-20 16:50 scottcheloha Status New => Under Review
2019-07-20 16:50 scottcheloha Assigned To => ajosey
2019-07-20 16:50 scottcheloha Name => Scott Cheloha
2019-07-20 16:50 scottcheloha Section => clock_nanosleep()
2019-07-20 16:50 scottcheloha Page Number => (where is the page number in the HTML version?)
2019-07-20 16:50 scottcheloha Line Number => (where is the line number in the HTML version?)
2019-07-20 17:08 Don Cragun Page Number (where is the page number in the HTML version?) => 671
2019-07-20 17:08 Don Cragun Line Number (where is the line number in the HTML version?) => 22756-22761
2019-07-20 17:08 Don Cragun Interp Status => ---
2019-07-20 17:12 scottcheloha Page Number 671 => (where is the page number in the HTML version?)
2019-07-20 17:12 scottcheloha Line Number 22756-22761 => (where is the line number in the HTML version?)
2019-07-20 17:12 scottcheloha Description Updated
2019-07-20 17:12 scottcheloha Desired Action Updated
2019-07-20 17:24 scottcheloha Desired Action Updated
2019-08-15 15:51 eblake Note Added: 0004522
2019-08-15 15:53 eblake Note Edited: 0004522
2022-07-14 15:36 Don Cragun Note Added: 0005887
2022-07-14 15:36 Don Cragun Status Under Review => Closed
2022-07-14 15:36 Don Cragun Resolution Open => Rejected