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

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