master
h 112 lines 3.66 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_DICTIONARY_LOCKS_H
4 #define NETDATA_DICTIONARY_LOCKS_H
5
6 #include "dictionary-internals.h"
7
8 // ----------------------------------------------------------------------------
9 // dictionary locks
10
11 static inline size_t dictionary_locks_init(DICTIONARY *dict) {
12 if(likely(!is_dictionary_single_threaded(dict))) {
13 rw_spinlock_init(&dict->index.rw_spinlock);
14 rw_spinlock_init(&dict->items.rw_spinlock);
15 }
16
17 return 0;
18 }
19
20 static inline size_t dictionary_locks_destroy(DICTIONARY *dict __maybe_unused) {
21 return 0;
22 }
23
24 static inline void ll_recursive_lock_set_thread_as_writer(DICTIONARY *dict) {
25 pid_t expected = 0, desired = gettid_cached();
26 if(!__atomic_compare_exchange_n(&dict->items.writer_pid, &expected, desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED))
27 fatal("DICTIONARY: Cannot set thread %d as exclusive writer, expected %d, desired %d, found %d.", gettid_cached(), expected, desired, __atomic_load_n(&dict->items.writer_pid, __ATOMIC_RELAXED));
28 }
29
30 static inline void ll_recursive_unlock_unset_thread_writer(DICTIONARY *dict) {
31 pid_t expected = gettid_cached(), desired = 0;
32 if(!__atomic_compare_exchange_n(&dict->items.writer_pid, &expected, desired, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED))
33 fatal("DICTIONARY: Cannot unset thread %d as exclusive writer, expected %d, desired %d, found %d.", gettid_cached(), expected, desired, __atomic_load_n(&dict->items.writer_pid, __ATOMIC_RELAXED));
34 }
35
36 static inline bool ll_recursive_lock_is_thread_the_writer(DICTIONARY *dict) {
37 pid_t tid = gettid_cached();
38 return tid > 0 && tid == __atomic_load_n(&dict->items.writer_pid, __ATOMIC_RELAXED);
39 }
40
41 static inline void ll_recursive_lock(DICTIONARY *dict, char rw) {
42 if(unlikely(is_dictionary_single_threaded(dict)))
43 return;
44
45 if(ll_recursive_lock_is_thread_the_writer(dict)) {
46 dict->items.writer_depth++;
47 return;
48 }
49
50 if(rw == DICTIONARY_LOCK_READ || rw == DICTIONARY_LOCK_REENTRANT || rw == 'R') {
51 // read lock
52 rw_spinlock_read_lock(&dict->items.rw_spinlock);
53 }
54 else {
55 // write lock
56 rw_spinlock_write_lock(&dict->items.rw_spinlock);
57 ll_recursive_lock_set_thread_as_writer(dict);
58 }
59 }
60
61 static inline void ll_recursive_unlock(DICTIONARY *dict, char rw) {
62 if(unlikely(is_dictionary_single_threaded(dict)))
63 return;
64
65 if(ll_recursive_lock_is_thread_the_writer(dict) && dict->items.writer_depth > 0) {
66 dict->items.writer_depth--;
67 return;
68 }
69
70 if(rw == DICTIONARY_LOCK_READ || rw == DICTIONARY_LOCK_REENTRANT || rw == 'R') {
71 // read unlock
72
73 rw_spinlock_read_unlock(&dict->items.rw_spinlock);
74 }
75 else {
76 // write unlock
77
78 ll_recursive_unlock_unset_thread_writer(dict);
79
80 rw_spinlock_write_unlock(&dict->items.rw_spinlock);
81 }
82 }
83
84 static inline void dictionary_index_lock_rdlock(DICTIONARY *dict) {
85 if(unlikely(is_dictionary_single_threaded(dict)))
86 return;
87
88 rw_spinlock_read_lock(&dict->index.rw_spinlock);
89 }
90
91 static inline void dictionary_index_rdlock_unlock(DICTIONARY *dict) {
92 if(unlikely(is_dictionary_single_threaded(dict)))
93 return;
94
95 rw_spinlock_read_unlock(&dict->index.rw_spinlock);
96 }
97
98 static inline void dictionary_index_lock_wrlock(DICTIONARY *dict) {
99 if(unlikely(is_dictionary_single_threaded(dict)))
100 return;
101
102 rw_spinlock_write_lock(&dict->index.rw_spinlock);
103 }
104 static inline void dictionary_index_wrlock_unlock(DICTIONARY *dict) {
105 if(unlikely(is_dictionary_single_threaded(dict)))
106 return;
107
108 rw_spinlock_write_unlock(&dict->index.rw_spinlock);
109 }
110
111
112 #endif //NETDATA_DICTIONARY_LOCKS_H