Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

win: more reliable uv__hrtime precision #292

Closed
wants to merge 1 commit into from

Conversation

Fishrock123
Copy link
Contributor

Eliminates floating-point operations that can cause precision loss.

Thanks to @Arnavion for suggesting the fix:
nodejs/node#1272 (comment)

(And IRC discussion in #io.js: http://logs.libuv.org/io.js/latest#18:25:27.988)

Note: first time writing any C.
Also, I don't have a windows machine configured to test this on.

@Fishrock123
Copy link
Contributor Author

Possibly related to nodejs/node-v0.x-archive#8960

@saghul
Copy link
Member

saghul commented Mar 26, 2015

/cc @piscisaureus or @orangemocha care to review?

@saghul saghul added the windows label Mar 26, 2015
@@ -59,7 +59,7 @@ static char *process_title;
static CRITICAL_SECTION process_title_lock;

/* Interval (in seconds) of the high-resolution clock. */
static double hrtime_interval_ = 0;
static long hrtime_interval_ = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

long is 32 bits on Windows, I think you want uint64_t.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return from .QuadPart is LONGLONG apparently. Same thing as uint64_t?

https://msdn.microsoft.com/en-us/library/windows/desktop/aa383713(v=vs.85).aspx

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost. LONGLONG equals int64_t.

@Fishrock123
Copy link
Contributor Author

Ideally, uv__hrtime would just take (uint64_t scale) also, but I'm not sure that change can be made?

@@ -484,7 +484,7 @@ uint64_t uv__hrtime(double scale) {
* performance counter interval, integer math could cause this computation
* to overflow. Therefore we resort to floating point math.
*/
return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale);
return (uint64_t) (counter.QuadPart * (long) scale / hrtime_interval_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use long. That's 32-bit!

@Fishrock123
Copy link
Contributor Author

Updated, PTAL. (sorry, forgot about the whole long and longlong deal. :3)

@@ -59,7 +59,7 @@ static char *process_title;
static CRITICAL_SECTION process_title_lock;

/* Interval (in seconds) of the high-resolution clock. */
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to self: update this comment comment(s).

@orangemocha
Copy link
Contributor

-1
There is no guarantee on the range of hrtime_interval_ (or frequency). That's why floating point was used in the first place.

@Fishrock123
Copy link
Contributor Author

@orangemocha perhaps it would be better to use a separate hrtime impl for timeouts then? https://github.com/libuv/libuv/blob/v1.x/src/win/timer.c#L32

@@ -59,7 +59,7 @@ static char *process_title;
static CRITICAL_SECTION process_title_lock;

/* Interval (in seconds) of the high-resolution clock. */
static double hrtime_interval_ = 0;
static uint64_t hrtime_interval_ = 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename it to hrtimer_frequency_ instead of interval?

@Fishrock123
Copy link
Contributor Author

Updated to use (counter.QuadPart / hrtime_interval_) * scale Which is better than what was there.

To actually do it with 128 bit, I think it would have to be one of these two to do the multiplication:

https://msdn.microsoft.com/en-us/library/windows/desktop/hh802934(v=vs.85).aspx
vs
https://msdn.microsoft.com/en-us/library/windows/desktop/jj635748(v=vs.85).aspx

But I really don't grok how they work. Also, it looks like bits would be lost in the conversion back to 64bit anyways, since windows does not have a 128bit divide.

Reduces floating-point operations that can cause precision loss.

Thanks to @Arnavion for suggesting the fix:
nodejs/node#1272 (comment)
/* Interval (in seconds) of the high-resolution clock. */
static double hrtime_interval_ = 0;
/* Interval of the high-resolution clock. */
static uint64_t hrtime_interval_ = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the comments, but I'm not 100% sure what unit this is now in

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My old comment still stands. This isn't an interval now - it's a frequency (Hz).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants