diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-26 08:15:24 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-26 08:15:35 +0000 |
commit | f09848204fa5283d21ea43e262ee41aa578e1808 (patch) | |
tree | c62385d7adf209fa6a798635954d887f718fb3fb /src/libnetdata/locks | |
parent | Releasing debian version 1.46.3-2. (diff) | |
download | netdata-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.c | 82 | ||||
-rw-r--r-- | src/libnetdata/locks/locks.h | 31 |
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); |