diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2019-09-13 18:56:08 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2019-09-20 19:17:22 +0200 |
commit | e503c988d825e0eaf5f56ed8dd68b318b3e43c04 (patch) | |
tree | 85527c3ea1f78c35eaf02df1c0584f16a88d9511 /CommonLibs/Threads.h | |
parent | ee2ba19cec96347d11e3661077ef3c4c0eb068c2 (diff) |
radioInterface: Atomically fetch and change underrun variable
Otherwise, it could happen that underrun events are lost:
TxLower (isUnderrun): RxLower (pullBuffer):
read(underrun)
read(underrun)
write(underrun, |val) [maybe underrun becomes TRUE]
write(underrun, false)
Similary, it could happen the other direction if atomic was only applied
to isUnderrun:
TxLower (isUnderrun): RxLower (pullBuffer):
read(underrun) -> true
read(underrun)-> true
write(underrun, false)
write(underrun, true|val) where val=false
So in here isUnderrun would return true twice while it should only
return one.
Change-Id: I684e0a5d2a9583a161d5a6593559b3a9e7cd57e3
Diffstat (limited to 'CommonLibs/Threads.h')
-rw-r--r-- | CommonLibs/Threads.h | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/CommonLibs/Threads.h b/CommonLibs/Threads.h index 4cc0884..df61c72 100644 --- a/CommonLibs/Threads.h +++ b/CommonLibs/Threads.h @@ -28,6 +28,8 @@ #ifndef THREADS_H #define THREADS_H +#include "config.h" + #include <pthread.h> #include <iostream> #include <assert.h> @@ -188,8 +190,30 @@ class Thread { void cancel() { pthread_cancel(mThread); } }; - - +#ifdef HAVE_ATOMIC_OPS +#define osmo_trx_sync_fetch_and_and(ptr, value) __sync_fetch_and_and((ptr), (value)) +#define osmo_trx_sync_or_and_fetch(ptr, value) __sync_or_and_fetch((ptr), (value)) +#else +extern pthread_mutex_t atomic_ops_mutex; +static inline int osmo_trx_sync_fetch_and_and(int *ptr, int value) +{ + pthread_mutex_lock(&atomic_ops_mutex); + int tmp = *ptr; + *ptr &= value; + pthread_mutex_unlock(&atomic_ops_mutex); + return tmp; +} + +static inline int osmo_trx_sync_or_and_fetch(int *ptr, int value) +{ + int tmp; + pthread_mutex_lock(&atomic_ops_mutex); + *ptr |= value; + tmp = *ptr; + pthread_mutex_unlock(&atomic_ops_mutex); + return tmp; +} +#endif #endif // vim: ts=4 sw=4 |