Repository navigation
Fix test_futimens_nodefs under Windows - #27801
Merged
sbc100 merged 1 commit intoSep 29, 2026
Merged
Conversation
In emscripten-core#27794 we clamped sub-second timestamps near the 1-second boundary to prevent double-precision rounding from incrementing the second. However, under Windows, Node.js (`libuv`) converts Unix timestamps to Windows `FILETIME` (100-nanosecond intervals since Jan 1, 1601 UTC): filetime = (time + 11644473600) * 10000000; Adding the 11.6 billion second epoch offset reduces floating-point precision (1 ULP becomes ~1.9 microseconds). When `tv_nsec` was close to 1e9 (e.g. 999,999,900 ns in `test_futimens`), adding the offset still rounded the result up into the next integer second on Windows. Instead of performing floating-point clamping near `maxSec`, round `tv_nsec` down to the nearest 10 microseconds (10,000 ns). This leaves sufficient headroom below the next whole second while preserving sub-millisecond timestamp precision. See: emscripten-core#25280
sbc100
force-pushed
the
fix_test_futimens_nodefs_windows
branch
from
September 29, 2026 20:55
aaa62fb to
fac100a
Compare
brendandahl
reviewed
Sep 29, 2026
Comment on lines
+1102
to
+1103
| tv_nsec = (tv_nsec / 10000 | 0) * 10000; | ||
| return (tv_sec + (tv_nsec / 1e9)) * 1000; |
Collaborator
There was a problem hiding this comment.
A little less readable, but avoids one lossy round.
Suggested change
| tv_nsec = (tv_nsec / 10000 | 0) * 10000; | |
| return (tv_sec + (tv_nsec / 1e9)) * 1000; | |
| return (tv_sec * 1000) + ((tv_nsec / 10000 | 0) / 100); |
Collaborator
Author
There was a problem hiding this comment.
Gemini seems sure that these are equivalent, especially since the consumer of these values fs.utimesSync expects seconds anyway, so we do do the decide by 1000 there anyway: basically we do utimes(arg, atime / 1000, mtime / 1000).
I kind of like the proposed approach in this PR for readability.
brendandahl
approved these changes
Sep 29, 2026
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In #27794 we clamped sub-second timestamps near the 1-second boundary
to prevent double-precision rounding from incrementing the second.
However, under Windows, Node.js (
libuv) converts Unix timestamps toWindows
FILETIME(100-nanosecond intervals since Jan 1, 1601 UTC):filetime = (time + 11644473600) * 10000000;
Adding the 11.6 billion second epoch offset reduces floating-point
precision (1 ULP becomes ~1.9 microseconds). When
tv_nsecwas closeto 1e9 (e.g. 999,999,900 ns in
test_futimens), adding the offsetstill rounded the result up into the next integer second on Windows.
Instead of performing floating-point clamping near
maxSec, roundtv_nsecdown to the nearest 10 microseconds (10,000 ns). This leavessufficient headroom below the next whole second while preserving
sub-millisecond timestamp precision.
See: #25280