aboutsummaryrefslogtreecommitdiffstats
path: root/CommonLibs/Threads.h
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-09-13 18:56:08 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2019-09-20 19:17:22 +0200
commite503c988d825e0eaf5f56ed8dd68b318b3e43c04 (patch)
tree85527c3ea1f78c35eaf02df1c0584f16a88d9511 /CommonLibs/Threads.h
parentee2ba19cec96347d11e3661077ef3c4c0eb068c2 (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.h28
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