summaryrefslogtreecommitdiffstats
path: root/src/libnetdata/locks
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-26 08:15:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-26 08:15:35 +0000
commitf09848204fa5283d21ea43e262ee41aa578e1808 (patch)
treec62385d7adf209fa6a798635954d887f718fb3fb /src/libnetdata/locks
parentReleasing debian version 1.46.3-2. (diff)
downloadnetdata-f09848204fa5283d21ea43e262ee41aa578e1808.tar.xz
netdata-f09848204fa5283d21ea43e262ee41aa578e1808.zip
Merging upstream version 1.47.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libnetdata/locks')
-rw-r--r--src/libnetdata/locks/locks.c82
-rw-r--r--src/libnetdata/locks/locks.h31
2 files changed, 94 insertions, 19 deletions
diff --git a/src/libnetdata/locks/locks.c b/src/libnetdata/locks/locks.c
index d01ee29f1..424b86ce9 100644
--- a/src/libnetdata/locks/locks.c
+++ b/src/libnetdata/locks/locks.c
@@ -224,14 +224,24 @@ int __netdata_rwlock_trywrlock(netdata_rwlock_t *rwlock) {
// spinlock implementation
// https://www.youtube.com/watch?v=rmGJc9PXpuE&t=41s
-void spinlock_init(SPINLOCK *spinlock) {
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+void spinlock_init(SPINLOCK *spinlock)
+{
+ netdata_mutex_init(&spinlock->inner);
+}
+#else
+void spinlock_init(SPINLOCK *spinlock)
+{
memset(spinlock, 0, sizeof(SPINLOCK));
}
+#endif
-static inline void spinlock_lock_internal(SPINLOCK *spinlock) {
-#ifdef NETDATA_INTERNAL_CHECKS
+#ifndef SPINLOCK_IMPL_WITH_MUTEX
+static inline void spinlock_lock_internal(SPINLOCK *spinlock)
+{
+ #ifdef NETDATA_INTERNAL_CHECKS
size_t spins = 0;
-#endif
+ #endif
for(int i = 1;
__atomic_load_n(&spinlock->locked, __ATOMIC_RELAXED) ||
@@ -239,9 +249,10 @@ static inline void spinlock_lock_internal(SPINLOCK *spinlock) {
; i++
) {
-#ifdef NETDATA_INTERNAL_CHECKS
+ #ifdef NETDATA_INTERNAL_CHECKS
spins++;
-#endif
+ #endif
+
if(unlikely(i == 8)) {
i = 0;
tinysleep();
@@ -250,23 +261,29 @@ static inline void spinlock_lock_internal(SPINLOCK *spinlock) {
// we have the lock
-#ifdef NETDATA_INTERNAL_CHECKS
+ #ifdef NETDATA_INTERNAL_CHECKS
spinlock->spins += spins;
spinlock->locker_pid = gettid_cached();
-#endif
+ #endif
nd_thread_spinlock_locked();
}
+#endif // SPINLOCK_IMPL_WITH_MUTEX
-static inline void spinlock_unlock_internal(SPINLOCK *spinlock) {
-#ifdef NETDATA_INTERNAL_CHECKS
+#ifndef SPINLOCK_IMPL_WITH_MUTEX
+static inline void spinlock_unlock_internal(SPINLOCK *spinlock)
+{
+ #ifdef NETDATA_INTERNAL_CHECKS
spinlock->locker_pid = 0;
-#endif
+ #endif
+
__atomic_clear(&spinlock->locked, __ATOMIC_RELEASE);
nd_thread_spinlock_unlocked();
}
+#endif // SPINLOCK_IMPL_WITH_MUTEX
+#ifndef SPINLOCK_IMPL_WITH_MUTEX
static inline bool spinlock_trylock_internal(SPINLOCK *spinlock) {
if(!__atomic_load_n(&spinlock->locked, __ATOMIC_RELAXED) &&
!__atomic_test_and_set(&spinlock->locked, __ATOMIC_ACQUIRE)) {
@@ -277,36 +294,79 @@ static inline bool spinlock_trylock_internal(SPINLOCK *spinlock) {
return false;
}
+#endif // SPINLOCK_IMPL_WITH_MUTEX
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+void spinlock_lock(SPINLOCK *spinlock)
+{
+ netdata_mutex_lock(&spinlock->inner);
+}
+#else
void spinlock_lock(SPINLOCK *spinlock)
{
spinlock_lock_internal(spinlock);
}
+#endif
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+void spinlock_unlock(SPINLOCK *spinlock)
+{
+ netdata_mutex_unlock(&spinlock->inner);
+}
+#else
void spinlock_unlock(SPINLOCK *spinlock)
{
spinlock_unlock_internal(spinlock);
}
+#endif
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+bool spinlock_trylock(SPINLOCK *spinlock)
+{
+ return netdata_mutex_trylock(&spinlock->inner) == 0;
+}
+#else
bool spinlock_trylock(SPINLOCK *spinlock)
{
return spinlock_trylock_internal(spinlock);
}
+#endif
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+void spinlock_lock_cancelable(SPINLOCK *spinlock)
+{
+ netdata_mutex_lock(&spinlock->inner);
+}
+#else
void spinlock_lock_cancelable(SPINLOCK *spinlock)
{
spinlock_lock_internal(spinlock);
}
+#endif
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+void spinlock_unlock_cancelable(SPINLOCK *spinlock)
+{
+ netdata_mutex_unlock(&spinlock->inner);
+}
+#else
void spinlock_unlock_cancelable(SPINLOCK *spinlock)
{
spinlock_unlock_internal(spinlock);
}
+#endif
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+bool spinlock_trylock_cancelable(SPINLOCK *spinlock)
+{
+ return netdata_mutex_trylock(&spinlock->inner) == 0;
+}
+#else
bool spinlock_trylock_cancelable(SPINLOCK *spinlock)
{
return spinlock_trylock_internal(spinlock);
}
+#endif
// ----------------------------------------------------------------------------
// rw_spinlock implementation
diff --git a/src/libnetdata/locks/locks.h b/src/libnetdata/locks/locks.h
index d3873c295..c05c65fe2 100644
--- a/src/libnetdata/locks/locks.h
+++ b/src/libnetdata/locks/locks.h
@@ -6,19 +6,34 @@
#include "../libnetdata.h"
#include "../clocks/clocks.h"
+// #ifdef OS_WINDOWS
+// #define SPINLOCK_IMPL_WITH_MUTEX
+// #endif
+
typedef pthread_mutex_t netdata_mutex_t;
#define NETDATA_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-typedef struct netdata_spinlock {
- bool locked;
-#ifdef NETDATA_INTERNAL_CHECKS
- pid_t locker_pid;
- size_t spins;
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+ typedef struct netdata_spinlock
+ {
+ netdata_mutex_t inner;
+ } SPINLOCK;
+#else
+ typedef struct netdata_spinlock
+ {
+ bool locked;
+ #ifdef NETDATA_INTERNAL_CHECKS
+ pid_t locker_pid;
+ size_t spins;
+ #endif
+ } SPINLOCK;
#endif
-} SPINLOCK;
-#define NETDATA_SPINLOCK_INITIALIZER \
- { .locked = false }
+#ifdef SPINLOCK_IMPL_WITH_MUTEX
+#define NETDATA_SPINLOCK_INITIALIZER { .inner = PTHREAD_MUTEX_INITIALIZER }
+#else
+#define NETDATA_SPINLOCK_INITIALIZER { .locked = false }
+#endif
void spinlock_init(SPINLOCK *spinlock);
void spinlock_lock(SPINLOCK *spinlock);