RFR: 8212826: Make PtrQueue free list lock-free
kim.barrett at oracle.com
Wed Jan 9 21:48:35 UTC 2019
Please review this change to BufferNode::Allocator to eliminate the
Mutex protecting the free-list, instead using a lock-free free-list.
This eliminates the need for the (access rank) free list lock for the
SATB and DirtyCard buffer allocator.
Part of this change is the introduction of a LockFreeStack utility
class template. This class doesn't attempt to solve the ABA problem,
instead leaving that to the client. The Allocator uses GlobalCounter
to solve the problem. (Other existing potential uses cases have
separate phases for push and pop, don't recycle objects, or have other
solutions.) Popping a buffer from the free list is done within a read
critical section. A buffer is added to the free list only after an
associated write synchronization is performed.
Unfortunately, the API for LockFreeStack<> isn't quite what we would
prefer. We would like this class's signature to be
template<typename T, T* volatile T::*next> class LockFreeStack;
but it is instead
template<typename T, T* volatile* (*next_ptr)(T&)> class LockFreeStack;
This is due to a bug in Solaris Studio's handling of pointer to data
member references within the class declaration (where the class is
incomplete). (Visual Studio 2013 (not before or after) had a similar
Performance testing found no significant difference. That's expected,
since any previous contention on the buffer allocator free list lock
will be closely associated with contention on the completed buffer
list lock. (I'm looking at ways to do something about the latter.)
However, on the new stress test, buffers cycle through more than twice
as fast with the lock-free allocator than with a locking allocator.
Note: This is a build breaking change for Shenandoah; its buffer
allocator construction will need to be updated.
More information about the hotspot-gc-dev