(10) (M) RFR: 8174231: Factor out and share PlatformEvent and Parker code for POSIX systems (original) (raw)

David Holmes david.holmes at oracle.com
Fri May 26 07:27:00 UTC 2017


Robbin, Dan,

Below is a modified version of the refactored to_abstime code that Robbin suggested.

Robbin: there were a couple of issues with your version. For relative time the timeout is always in nanoseconds - the "unit" only tells you what form the "now_part_sec" is - nanos or micros. And the calc_abs_time always has a deadline in millis. So I simplified and did a little renaming, and tracked max_secs in debug_only instead of returning it.

Please let me know what you think.

Thanks, David

// Calculate a new absolute time that is "timeout" nanoseconds from "now". // "unit" indicates the unit of "now_part_sec" (may be nanos or micros depending // on which clock is being used). static void calc_rel_time(timespec* abstime, jlong timeout, jlong now_sec, jlong now_part_sec, jlong unit) { time_t max_secs = now_sec + MAX_SECS;

jlong seconds = timeout / NANOUNITS; timeout %= NANOUNITS; // remaining nanos

if (seconds >= MAX_SECS) { // More seconds than we can add, so pin to max_secs. abstime->tv_sec = max_secs; abstime->tv_nsec = 0; } else { abstime->tv_sec = now_sec + seconds; long nanos = (now_part_sec * (NANOUNITS / unit)) + timeout; if (nanos >= NANOUNITS) { // overflow abstime->tv_sec += 1; nanos -= NANOUNITS; } abstime->tv_nsec = nanos; } }

// Unpack the given deadline in milliseconds since the epoch, into the given timespec. // The current time in seconds is also passed in to enforce an upper bound as discussed above. static void unpack_abs_time(timespec* abstime, jlong deadline, jlong now_sec) { time_t max_secs = now_sec + MAX_SECS;

jlong seconds = deadline / MILLIUNITS; jlong millis = deadline % MILLIUNITS;

if (seconds >= max_secs) { // Absolute seconds exceeds allowed max, so pin to max_secs. abstime->tv_sec = max_secs; abstime->tv_nsec = 0; } else { abstime->tv_sec = seconds; abstime->tv_nsec = millis * (NANOUNITS / MILLIUNITS); } }

static void to_abstime(timespec* abstime, jlong timeout, bool isAbsolute) {

DEBUG_ONLY(int max_secs = MAX_SECS;)

if (timeout < 0) { timeout = 0; }

#ifdef SUPPORTS_CLOCK_MONOTONIC

if (_use_clock_monotonic_condattr && !isAbsolute) { struct timespec now; int status = _clock_gettime(CLOCK_MONOTONIC, &now); assert_status(status == 0, status, "clock_gettime"); calc_rel_time(abstime, timeout, now.tv_sec, now.tv_nsec, NANOUNITS); DEBUG_ONLY(max_secs += now.tv_sec;) } else {

#else

{ // Match the block scope.

#endif // SUPPORTS_CLOCK_MONOTONIC

 // Time-of-day clock is all we can reliably use.
 struct timeval now;
 int status = gettimeofday(&now, NULL);
 assert(status == 0, "gettimeofday");
 if (isAbsolute) {
   unpack_abs_time(abstime, timeout, now.tv_sec);
 }
 else {
   calc_rel_time(abstime, timeout, now.tv_sec, now.tv_usec, MICROUNITS);
 }
 DEBUG_ONLY(max_secs += now.tv_sec;)

}

assert(abstime->tv_sec >= 0, "tv_sec < 0"); assert(abstime->tv_sec <= max_secs, "tv_sec > max_secs"); assert(abstime->tv_nsec >= 0, "tv_nsec < 0"); assert(abstime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");

}



More information about the hotspot-dev mailing list