[concurrency-interest] On park and unpark

Nathan and Ila Reynolds nathanila at gmail.com
Fri Aug 25 14:45:55 EDT 2017


So, if we switch this to a futex, then we can get rid of the 
cond_wait/cond_timedwait calls.  Is this correct?  If correct, then this 
change will slightly reduce CPU usage and probably worth the effort.  
The change may reduce the code complexity and reduce maintenance costs.  
At least, the change will reduce the number of emails about suggesting 
that park/unpark uses futexes.  ;)

-Nathan

On 8/25/2017 11:28 AM, Andrew Haley wrote:
> On 25/08/17 18:01, Nathan and Ila Reynolds wrote:
>> Last I heard (and this is old hearing), unpark() had to acquire the
>> mutex before checking the park permit flag.  From the sound of it, using
>> futex directly would allow for checking the park permit flag without
>> acquiring the mutex.  Hence, fewer atomic operations (i.e. no need to
>> acquire and release the mutex).  However, I could be very wrong since I
>> have never dug into the details and I am only working off of hearsay.
> Here's now it works now:
>
> void Parker::park(bool isAbsolute, jlong time) {
>
>    // Optional fast-path check:
>    // Return immediately if a permit is available.
>    // We depend on Atomic::xchg() having full barrier semantics
>    // since we are doing a lock-free update to _counter.
>    if (Atomic::xchg(0, &_counter) > 0) return;
>
> ... stuff with timers and thread interrupts ...
>
>    // Don't wait if cannot get lock since interference arises from
>    // unblocking.  Also. check interrupt before trying wait
>    if (Thread::is_interrupted(thread, false) ||
>        os::Solaris::mutex_trylock(_mutex) != 0) {
>      return;
>    }
>
>    if (_counter > 0)  { // no wait needed
>      _counter = 0;
>      status = os::Solaris::mutex_unlock(_mutex);
>      assert(status == 0, "invariant");
>      // Paranoia to ensure our locked and lock-free paths interact
>      // correctly with each other and Java-level accesses.
>      OrderAccess::fence();
>      return;
>    }
>
> ...
>
>    // Do this the hard way by blocking ...
>    // See http://monaco.sfbay/detail.jsf?cr=5094058.
>    if (time == 0) {
>      status = os::Solaris::cond_wait(_cond, _mutex);
>    } else {
>      status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime);
>    }
>
> But even if we had had to lock the mutex to read the _counter, it's
> just a CAS which would always succeed unless we were being unparked.
>

-- 
-Nathan



More information about the Concurrency-interest mailing list