-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix formatting and a bug in clock_getres, and add unittest
- Loading branch information
Showing
6 changed files
with
86 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
1.23.2 | ||
1.23.3 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include <time.h> | ||
#include <errno.h> | ||
#include <stdio.h> | ||
|
||
int main() { | ||
clockid_t clocks[] = { CLOCK_REALTIME, CLOCK_MONOTONIC }; | ||
for (int i = 0; i < (int)(sizeof(clocks)/sizeof(*clocks)); ++i) { | ||
printf("%sTests for clockid_t=%d\n-----------------\n", | ||
i == 0 ? "" : "\n", clocks[i]); | ||
struct timespec ts; | ||
int rv = clock_getres(clocks[i], &ts); | ||
if (rv) | ||
printf("clock_getres failed\n"); | ||
else if (ts.tv_sec || ts.tv_nsec > 50000000) | ||
printf("clock_getres resolution not enough (%ld.%09ld)\n", | ||
(long)ts.tv_sec, ts.tv_nsec); | ||
else | ||
printf("clock_getres resolution OK\n"); | ||
rv = clock_gettime(clocks[i], &ts); | ||
printf(rv ? "clock_gettime failed\n" : "clock_gettime OK\n"); | ||
errno = 0; | ||
if (clock_settime(clocks[i], &ts) == 0) | ||
printf("clock_settime should have failed\n"); | ||
else if (errno == EPERM && clocks[i] == CLOCK_REALTIME) | ||
printf("clock_settime failed with EPERM (OK)\n"); | ||
else if (errno == EINVAL && clocks[i] == CLOCK_MONOTONIC) | ||
printf("clock_settime failed with EINVAL (OK)\n"); | ||
else | ||
printf("clock_settime failed with wrong error code\n"); | ||
} | ||
clockid_t bogus = 42; | ||
struct timespec ts; | ||
printf("\nTests for clockid_t=%d\n-----------------\n", bogus); | ||
if (clock_gettime(bogus, &ts) == 0 || errno != EINVAL) | ||
printf("clock_gettime should have failed\n"); | ||
else | ||
printf("clock_gettime failed with EINVAL (OK)\n"); | ||
if (clock_getres(bogus, &ts) == 0 || errno != EINVAL) | ||
printf("clock_getres should have failed\n"); | ||
else | ||
printf("clock_getres failed with EINVAL (OK)\n"); | ||
if (clock_settime(bogus, &ts) == 0 || errno != EINVAL) | ||
printf("clock_settime should have failed\n"); | ||
else | ||
printf("clock_settime failed with EINVAL (OK)\n"); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
Tests for clockid_t=0 | ||
----------------- | ||
clock_getres resolution OK | ||
clock_gettime OK | ||
clock_settime failed with EPERM (OK) | ||
|
||
Tests for clockid_t=1 | ||
----------------- | ||
clock_getres resolution OK | ||
clock_gettime OK | ||
clock_settime failed with EINVAL (OK) | ||
|
||
Tests for clockid_t=42 | ||
----------------- | ||
clock_gettime failed with EINVAL (OK) | ||
clock_getres failed with EINVAL (OK) | ||
clock_settime failed with EINVAL (OK) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
I traced back a newly occurring problem re clock_gettime() to this patch of yours. Specifically, I have built a legacy code base which invokes clock_gettime() with CLOCK_MONOTONIC. This used to work fine before a recent chunk of patches that start using the window.performance high-precision timing API. While I like this change, I don't think that rejecting clock_gettime() invocations with CLOCK_MONOTONIC on platforms not supporting the Performance API is justified. Even if Date.now() is not always monotonic (even though I don't understand when it wouldn't be), this is Javascript land, and I don't think that cross-compiled code should be/has to be that picky. After all, Javascript is ill-suited to all purposes where this would matter, such as programming real-time software.
As a side note: the Performance API is available in Workers on some platforms (Chrome, Opera). I will submit a patch for this isolated problem and also submit another patch, proposing to relax the "monotonicity" criterion such that a Date.now() fallback qualifies.
Soeren
ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Date.now
can just call an underlying system call, which might not be monotonic. I'm not sure how common that is, butperformance.now
was designed in part to solve the problem ofDate.now
not being monotonic.I think we should default to rejecting
MONOTONIC
if all we have isDate.now
as we currently do, to be as compatible with other platforms as possible. However, what do you think about the following options?performance.now
, we can "monotonize"Date.now
(by ensuring we return values >= than the last).Date.now
as monotonic.ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I remember now,
Date.now
can easily be non-monotonic if the system time changes. Given that, option 1 that I just mentioned is probably not a good idea.ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my last comment, one main reason it can be nonmonotonic is that the system time can change.
Date.now
is literally the time since the epoch, so if daylight savings happens or the system syncs with a network clock,Date.now
can definitely be nonmonotonic.Still, we could add an option, off by default, to ignore that, as in 2 above.
ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible to "monotonize" the wall clock if you prefer monotonicity to constant-length seconds. One option is to do something like this:
Of course, it's all trade-offs! You get monotonicity, but you don't get constant-length seconds with this API because the values returned by the API don't advance when the underlying clock skips. In an extreme case, if the system clock jumps every second (say) then you could call the API every second and it would always return the same value, even though time is advancing -- it just can't detect that.
To be honest, the reason I wanted to prevent CLOCK_MONOTONIC from use Date.now is that our codebase already has sophisticated workarounds for platforms (embedded and old desktop OSes) without a monotonic timer -- in particular, we have cunning rescheduling of all our timer events when we detect clock skips forwards and backwards.
Forwards jumps are the killers! All you have to do is close a laptop lid and reopen it, and Date.now has basically jumped forwards, which a good CLOCK_MONOTONIC should not do (it doesn't include suspend time). I keep meaning to file a bug on Chrome and Firefox, which have different behaviour on this one depending on the OS they're running on in their window.performance implementation.
ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ef48462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, how about an option called "ASSUME_DATE_NOW_MONOTONIC" for option 2 from before?