@cryptotaxi247 / netdata-1 / commits / 456250a02

rw_spinlocks: allow recursive readers, even when writers are waiting (#19191)

revert preferring writers in rw_spinlocks - recursive read locks are required by dictionary

Costa Tsaousis committed Dec 12, 2024 at 11:51 UTC 456250a02fbe46795d94ee4f6e5d551a32117cab
2 files changed +6 -28
src/libnetdata/locks/rw-spinlock.c
+6 -27
@@ -7,26 +7,14 @@
7
8 void rw_spinlock_init_with_trace(RW_SPINLOCK *rw_spinlock, const char *func) {
9 rw_spinlock->readers = 0;
10 - rw_spinlock->writers_waiting = 0;
10 spinlock_init_with_trace(&rw_spinlock->spinlock, func);
11 }
12
13 void rw_spinlock_read_lock_with_trace(RW_SPINLOCK *rw_spinlock, const char *func) {
15 - size_t spins = 0;
16 - while(1) {
17 - spinlock_lock_with_trace(&rw_spinlock->spinlock, func);
18 - if (!rw_spinlock->writers_waiting) {
19 - __atomic_add_fetch(&rw_spinlock->readers, 1, __ATOMIC_RELAXED);
20 - spinlock_unlock_with_trace(&rw_spinlock->spinlock, func);
21 - break;
22 - }
23 -
24 - spinlock_unlock_with_trace(&rw_spinlock->spinlock, func);
25 - yield_the_processor(); // let the writer run
26 - spins++;
27 - }
14 + spinlock_lock_with_trace(&rw_spinlock->spinlock, func);
15 + __atomic_add_fetch(&rw_spinlock->readers, 1, __ATOMIC_RELAXED);
16 + spinlock_unlock_with_trace(&rw_spinlock->spinlock, func);
17
29 - worker_spinlock_contention(func, spins);
18 nd_thread_rwspinlock_read_locked();
19 }
20
@@ -44,24 +32,15 @@ void rw_spinlock_read_unlock_with_trace(RW_SPINLOCK *rw_spinlock, const char *fu
32
33 void rw_spinlock_write_lock_with_trace(RW_SPINLOCK *rw_spinlock, const char *func) {
34 size_t spins = 0;
47 - for(size_t i = 1; true ;i++) {
35 + while(true) {
36 spinlock_lock_with_trace(&rw_spinlock->spinlock, func);
37
50 - if(__atomic_load_n(&rw_spinlock->readers, __ATOMIC_RELAXED) == 0) {
51 - if(spins != 0)
52 - rw_spinlock->writers_waiting--;
38 + if(__atomic_load_n(&rw_spinlock->readers, __ATOMIC_RELAXED) == 0)
39 break;
54 - }
55 -
56 - if(spins == 0)
57 - rw_spinlock->writers_waiting++;
40
41 // Busy wait until all readers have released their locks.
42 spinlock_unlock_with_trace(&rw_spinlock->spinlock, func);
61 - if(i == 8 * 2) {
62 - i = 0;
63 - tinysleep();
64 - }
43 + tinysleep();
44 spins++;
45 }
46
src/libnetdata/locks/rw-spinlock.h
-1
@@ -8,7 +8,6 @@
8
9 typedef struct netdata_rw_spinlock {
10 int32_t readers;
11 - int32_t writers_waiting;
11 SPINLOCK spinlock;
12 } RW_SPINLOCK;
13