(10) (M) RFR: 8174231: Factor out and share PlatformEvent and Parker code for POSIX systems
David Holmes
david.holmes at oracle.com
Mon May 29 04:19:35 UTC 2017
Dan, Robbin, Thomas,
Okay here is the final ready to push version:
http://cr.openjdk.java.net/~dholmes/8174231/webrev.hotspot.v2/
this fixes all Dan's nits and refactors the time calculation code as
suggested by Robbin.
Thomas: if you are around and able, it would be good to get a final
sanity check on AIX. Thanks.
Testing:
- JPRT: -testset hotspot
-testset core
- manual:
- jtreg:java/util/concurrent
- various little test programs that try to validate sleep/wait times
to show early returns or unexpected delays
Thanks again for the reviews.
David
On 29/05/2017 10:29 AM, David Holmes wrote:
> On 27/05/2017 4:19 AM, Daniel D. Daugherty wrote:
>> On 5/26/17 1:27 AM, David Holmes wrote:
>>> 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.
>>
>> Looks OK to me. Nit comments below...
>
> Thanks Dan - more below.
>
>>>
>>>
>>> // 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) {
>>
>> There's an extra blank line here.
>
> Fixed.
>
>>>
>>> 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");
>>
>> assert_status() is used above, but assert() is used here. Why?
>
> Historical. assert_status was introduced for the pthread* and other
> posix funcs that return the error value rather than returning -1 and
> setting errno. gettimeofday is not one of those so still has the old
> assert. However, as someone pointed out a while ago you can use
> assert_status with these and pass errno as the "status". So I did that.
>
>>
>>> if (isAbsolute) {
>>> unpack_abs_time(abstime, timeout, now.tv_sec);
>>> }
>>> else {
>>
>> Inconsistent "else-branch" formatting.
>> I believe HotSpot style is "} else {"
>
> Fixed.
>
>>> 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");
>>
>> Why does the assert mesg have "nanos_per_sec" instead of
>> "NANOSECS_PER_SEC"?
>
> No reason. Actually that should now refer to NANOUNITS. Hmmm I can not
> recall why we have NANOUNITS and NANAOSECS_PER_SEC ... possibly an
> oversight.
>
>> There's an extra blank line here.
>
> Fixed.
>
> Will send out complete updated webrev soon.
>
> Thanks,
> David
>
>>>
>>> }
>>
>> Definitely looks and reads much cleaner.
>>
>> Dan
>>
More information about the hotspot-dev
mailing list