This patch optionally enables, at compile-time, OSV to use the lock-free mutex instead of the spin-lock-based mutex. To use the lock-free mutex, change the line "#undef LOCKFREE_MUTEX" in include/osv/mutex.h to "#define LOCKFREE_MUTEX".
LOCKFREE_MUTEX is currently disabled by default, awaiting a few more tests, but at this point I'm happy to say that beyond one known unrelated bug (see details below), it seems the lock-free mutex is fairly stable, and survives all tests and benchmarks I threw at it.
The remaining known bug involves a thread destruction race between complete() and join(): complete wake()s the joiner thread, which in rare cases can really quickly delete the thread's stack, before wake() returns, causing a crash on return from wake(). This bug is really unrelated to the lock-free mutex, but for some unknown reason I can only reproduce it with the lock-free mutex on the SPECjvm2008 "sunflow" benchmark.
To make lockfree::mutex our default mutex, this patch does the following when LOCKFREE_MUTEX is defined:
1. In core/mutex.cc, #ifndef away out the old mutex code, leaving the spinlock code in case someone wants to use it directly.
2. In include/osv/mutex.h, do different things in C++ and C (remember that lockfree::mutex is a C++ class, and cannot be used directly from C):
- In C++, simply make mutex and mutex_t aliases for lockfree::mutex.
- In C, make struct mutex and mutex_t an opaque 40-byte structure (in C++ compilation, we verify that this 40 is indeed the C++ class's length), and define the operations on it.
3. In libc/pthread.cc, if LOCKFREE_MUTEX, unfortunately the new mutex will not fit into pthread_mutex_t, and neither will condvar fit now into pthread_cond_t. So use a lazily allocated mutex or condvar, using the lazy_indirect<> template.
a2cb99d Optionally enable (disabled by default) lock-free mutex
core/mutex.cc | 9 +++++++--
include/osv/mutex.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
libc/pthread.cc | 46 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 105 insertions(+), 2 deletions(-)
Upstream: github.com