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