File indexing completed on 2026-01-08 10:33:34
0001 #ifndef __SSIATOMICS_HH__
0002 #define __SSIATOMICS_HH__
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <cstring>
0033
0034 #undef NEED_ATOMIC_MUTEX
0035
0036
0037
0038
0039 #if __cplusplus >= 201103L
0040 #include <atomic>
0041 #define Atomic(type) std::atomic<type>
0042 #define Atomic_IMP "C++11"
0043 #define Atomic_BEG(x)
0044 #define Atomic_DEC(x) x.fetch_sub(1,std::memory_order_relaxed)
0045 #define Atomic_GET(x) x.load(std::memory_order_relaxed)
0046 #define Atomic_GET_STRICT(x) x.load(std::memory_order_acquire)
0047 #define Atomic_INC(x) x.fetch_add(1,std::memory_order_relaxed)
0048 #define Atomic_SET(x,y) x.store(y,std::memory_order_relaxed)
0049 #define Atomic_SET_STRICT(x,y) x.store(y,std::memory_order_release)
0050 #define Atomic_ZAP(x) x.store(0,std::memory_order_relaxed)
0051 #define Atomic_END(x)
0052
0053
0054
0055
0056 #elif __GNUC__ == 4 && __GNUC_MINOR__ > 6
0057 #define Atomic(type) type
0058 #define Atomic_IMP "gnu-atomic"
0059 #define Atomic_BEG(x)
0060 #define Atomic_DEC(x) __atomic_fetch_sub(&x,1,__ATOMIC_RELAXED)
0061 #define Atomic_GET(x) __atomic_load_n (&x, __ATOMIC_RELAXED)
0062 #define Atomic_GET_STRICT(x) __atomic_load_n (&x, __ATOMIC_ACQUIRE)
0063 #define Atomic_INC(x) __atomic_fetch_add(&x,1,__ATOMIC_RELAXED)
0064 #define Atomic_SET(x,y) __atomic_store_n (&x,y,__ATOMIC_RELAXED)
0065 #define Atomic_SET_STRICT(x,y) __atomic_store_n (&x,y,__ATOMIC_RELEASE)
0066 #define Atomic_ZAP(x) __atomic_store_n (&x,0,__ATOMIC_RELAXED)
0067 #define Atomic_END(x)
0068
0069
0070
0071
0072
0073
0074 #elif HAVE_ATOMICS
0075 #define Atomic(type) type
0076 #define Atomic_IMP "gnu-sync"
0077 #define Atomic_BEG(x)
0078 #define Atomic_DEC(x) __sync_fetch_and_sub(&x, 1)
0079 #define Atomic_GET(x) __sync_fetch_and_or (&x, 0)
0080 #define Atomic_GET_STRICT(x) __sync_fetch_and_or (&x, 0)
0081 #define Atomic_INC(x) __sync_fetch_and_add(&x, 1)
0082 #define Atomic_SET(x,y) x=y,__sync_synchronize()
0083 #define Atomic_SET_STRICT(x,y) __sync_synchronize(),x=y,__sync_synchronize()
0084 #define Atomic_ZAP(x) __sync_fetch_and_and(&x, 0)
0085 #define Atomic_END(x)
0086
0087
0088
0089
0090 #else
0091 #define NEED_ATOMIC_MUTEX 1
0092 #define Atomic_IMP "missing"
0093 #define Atomic(type) type
0094 #define Atomic_BEG(x) pthread_mutex_lock(x)
0095 #define Atomic_DEC(x) x--
0096 #define Atomic_GET(x) x
0097 #define Atomic_INC(x) x++
0098 #define Atomic_SET(x,y) x = y
0099 #define Atomic_ZAP(x) x = 0
0100 #define Atomic_END(x) pthread_mutex_unlock(x)
0101 #endif
0102
0103
0104
0105
0106
0107 #include <pthread.h>
0108
0109 class XrdSsiMutex
0110 {
0111 public:
0112
0113 inline bool TryLock() {return pthread_mutex_trylock( &cs ) == 0;}
0114
0115 inline void Lock() {pthread_mutex_lock(&cs);}
0116
0117 inline void UnLock() {pthread_mutex_unlock(&cs);}
0118
0119 enum MutexType {Simple = 0, Recursive = 1};
0120
0121 XrdSsiMutex(MutexType mt=Simple)
0122 {int rc;
0123 if (mt == Simple) rc = pthread_mutex_init(&cs, NULL);
0124 else {pthread_mutexattr_t attr;
0125 if (!(rc = pthread_mutexattr_init(&attr)))
0126 {pthread_mutexattr_settype(&attr,
0127 PTHREAD_MUTEX_RECURSIVE);
0128 rc = pthread_mutex_init(&cs, &attr);
0129 }
0130 }
0131 if (rc) throw Errno2Text(rc);
0132 }
0133
0134 ~XrdSsiMutex() {pthread_mutex_destroy(&cs);}
0135
0136 protected:
0137
0138 pthread_mutex_t cs;
0139
0140 private:
0141 const char* Errno2Text(int ecode);
0142 };
0143
0144
0145
0146
0147
0148 class XrdSsiMutexMon
0149 {
0150 public:
0151
0152 inline void Lock(XrdSsiMutex *mutex)
0153 {if (mtx) {if (mtx != mutex) mtx->UnLock();
0154 else return;
0155 }
0156 mutex->Lock();
0157 mtx = mutex;
0158 };
0159
0160 inline void Lock(XrdSsiMutex &mutex) {Lock(&mutex);}
0161
0162 inline void Reset() {mtx = 0;}
0163
0164 inline void UnLock() {if (mtx) {mtx->UnLock(); mtx = 0;}}
0165
0166 XrdSsiMutexMon(XrdSsiMutex *mutex=0)
0167 {if (mutex) mutex->Lock();
0168 mtx = mutex;
0169 }
0170 XrdSsiMutexMon(XrdSsiMutex &mutex)
0171 {mutex.Lock();
0172 mtx = &mutex;
0173 }
0174
0175 ~XrdSsiMutexMon() {if (mtx) UnLock();}
0176 private:
0177 XrdSsiMutex *mtx;
0178 };
0179 #endif