[libcxx-commits] [libcxx] [libc++] add shared_recursive_mutex api (PR #82466)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 27 00:21:44 PST 2024


================
@@ -0,0 +1,61 @@
+#ifndef _SHARED_RECURSIVE_MUTEX_
+#define _SHARED_RECURSIVE_MUTEX_
+
+#include <cstdint>
+#include <mutex>
+#include <condition_variable>
+#include <thread>
+#include <shared_mutex>
+
+namespace std {
+/* Provides recurseve shared_mutex.
+ *
+ * 1. Function
+ *   |         type           |   policy       | Read Nesting | Read-write Nesting | Write-read Nesting | Write Nesting |
+ *   |  pthread_rwlock(glibc) |  Reader favor  |       Y      |      deadlock      |    return false    | return false  |
+ *   |  shared_mutex(gcc)     |  Reader favor  |       Y      |      deadlock      |       assert       |    assert     |
+ *   |  shared_mutex(llvm)    |  Write favor   |maybe deadlock|      deadlock      |      deadlock      |    deadlock   |
+ *   | shared_recursive_mutex |  Reader favor  |       Y      |      deadlock      |          Y         |       Y       |
+ *   Reasons for not supporting read/write nesting:
+ *     - The information about the read lock holder needs to be maintained, which affects the memory and performance.
+ *     - does not meet the contract of the read lock (no modification should be made during the hold period)
+ *
+ * 2. shared_mutex vs shared_recursive_mutex(SR) performance comparison
+ *   |       testcase       |  GCC RL  | GCC WL   | LLVM RL  |  LLVM WL |   SR RL  |   SR WL  |
+ *   |     1read 0write     | 7445029  |       0  | 3452907  |       0  | 3547000  |       0  |
+ *   |     0read 1write     |       0  | 5102869  |       0  | 7445029  |       0  | 3472935  |
+ *   |     1read 1write     |   47861  |   50153  |   31417  |  524955  |  224395  |  244908  |
+ *   |     2read 1write     |  444764  |   26655  |  120715  |  387924  |  397377  |  155332  |
+ *   |     4read 1write     | 1767244  |    9418  |  110139  |  214612  |  383453  |   21677  |
+ *   |     2read 2write     |  433766  |   25975  |   48125  |  312586  |  212341  |  117929  |
+ *   - base on ARMv7 8*A15
+ *   - The value is the number of lock operations performed by all threads in 10s. Larger is better.
+ *
+ * 3. shared_recursive_mutex support shared_lock and unique_lock.
+ */
+class shared_recursive_mutex {
+public:
+    shared_recursive_mutex() = default;
+    ~shared_recursive_mutex() = default;
+
+    shared_recursive_mutex(const shared_recursive_mutex &) = delete;
+    shared_recursive_mutex &operator = (const shared_recursive_mutex &) = delete;
+
+    void lock();
+    bool try_lock();
+    void unlock();
+
+    void lock_shared();
+    bool try_lock_shared();
+    void unlock_shared();
+
+private:
+    std::mutex mutex;
+    std::condition_variable cond;
+    pthread_t owner = 0;     // write owner.
+    uint32_t recursions = 0; // read lock recursions
+    uint32_t readers = 0;
----------------
frederick-vs-ja wrote:

Member names should be __uglified to avoid conflict with user-defined macros. Perhaps `mutex` is an exception, but it's confusing that there's both `std::mutex` and member `mutex`.

https://github.com/llvm/llvm-project/pull/82466


More information about the libcxx-commits mailing list