xrootd
XrdSsiAtomics.hh
Go to the documentation of this file.
1#ifndef __SSIATOMICS_HH__
2#define __SSIATOMICS_HH__
3/******************************************************************************/
4/* */
5/* X r d S s i A t o m i c s . h h */
6/* */
7/* (c) 2015 by the Board of Trustees of the Leland Stanford, Jr., University */
8/* Produced by Andrew Hanushevsky for Stanford University under contract */
9/* DE-AC02-76-SFO0515 with the Department of Energy */
10/* */
11/* This file is part of the XRootD software suite. */
12/* */
13/* XRootD is free software: you can redistribute it and/or modify it under */
14/* the terms of the GNU Lesser General Public License as published by the */
15/* Free Software Foundation, either version 3 of the License, or (at your */
16/* option) any later version. */
17/* */
18/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
19/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
20/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
21/* License for more details. */
22/* */
23/* You should have received a copy of the GNU Lesser General Public License */
24/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
25/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
26/* */
27/* The copyright holder's institutional names and contributor's names may not */
28/* be used to endorse or promote products derived from this software without */
29/* specific prior written permission of the institution or contributor. */
30/******************************************************************************/
31
32#include <string.h>
33
34#undef NEED_ATOMIC_MUTEX
35
36//-----------------------------------------------------------------------------
38//-----------------------------------------------------------------------------
39#if __cplusplus >= 201103L
40#include <atomic>
41#define Atomic(type) std::atomic<type>
42#define Atomic_IMP "C++11"
43#define Atomic_BEG(x)
44#define Atomic_DEC(x) x.fetch_sub(1,std::memory_order_relaxed)
45#define Atomic_GET(x) x.load(std::memory_order_relaxed)
46#define Atomic_GET_STRICT(x) x.load(std::memory_order_acquire)
47#define Atomic_INC(x) x.fetch_add(1,std::memory_order_relaxed)
48#define Atomic_SET(x,y) x.store(y,std::memory_order_relaxed)
49#define Atomic_SET_STRICT(x,y) x.store(y,std::memory_order_release)
50#define Atomic_ZAP(x) x.store(0,std::memory_order_relaxed)
51#define Atomic_END(x)
52
53//-----------------------------------------------------------------------------
55//-----------------------------------------------------------------------------
56#elif __GNUC__ == 4 && __GNUC_MINOR__ > 6
57#define Atomic(type) type
58#define Atomic_IMP "gnu-atomic"
59#define Atomic_BEG(x)
60#define Atomic_DEC(x) __atomic_fetch_sub(&x,1,__ATOMIC_RELAXED)
61#define Atomic_GET(x) __atomic_load_n (&x, __ATOMIC_RELAXED)
62#define Atomic_GET_STRICT(x) __atomic_load_n (&x, __ATOMIC_ACQUIRE)
63#define Atomic_INC(x) __atomic_fetch_add(&x,1,__ATOMIC_RELAXED)
64#define Atomic_SET(x,y) __atomic_store_n (&x,y,__ATOMIC_RELAXED)
65#define Atomic_SET_STRICT(x,y) __atomic_store_n (&x,y,__ATOMIC_RELEASE)
66#define Atomic_ZAP(x) __atomic_store_n (&x,0,__ATOMIC_RELAXED)
67#define Atomic_END(x)
68
69//-----------------------------------------------------------------------------
73//-----------------------------------------------------------------------------
74#elif HAVE_ATOMICS
75#define Atomic(type) type
76#define Atomic_IMP "gnu-sync"
77#define Atomic_BEG(x)
78#define Atomic_DEC(x) __sync_fetch_and_sub(&x, 1)
79#define Atomic_GET(x) __sync_fetch_and_or (&x, 0)
80#define Atomic_GET_STRICT(x) __sync_fetch_and_or (&x, 0)
81#define Atomic_INC(x) __sync_fetch_and_add(&x, 1)
82#define Atomic_SET(x,y) x=y,__sync_synchronize()
83#define Atomic_SET_STRICT(x,y) __sync_synchronize(),x=y,__sync_synchronize()
84#define Atomic_ZAP(x) __sync_fetch_and_and(&x, 0)
85#define Atomic_END(x)
86
87//-----------------------------------------------------------------------------
89//-----------------------------------------------------------------------------
90#else
91#define NEED_ATOMIC_MUTEX 1
92#define Atomic_IMP "missing"
93#define Atomic(type) type
94#define Atomic_BEG(x) pthread_mutex_lock(x)
95#define Atomic_DEC(x) x--
96#define Atomic_GET(x) x
97#define Atomic_INC(x) x++
98#define Atomic_SET(x,y) x = y
99#define Atomic_ZAP(x) x = 0
100#define Atomic_END(x) pthread_mutex_unlock(x)
101#endif
102
103/******************************************************************************/
104/* */
105/* X r d S s i M u t e x */
106/******************************************************************************/
107
108#include <pthread.h>
109
111{
112public:
113
114inline bool TryLock() {return pthread_mutex_trylock( &cs ) == 0;}
115
116inline void Lock() {pthread_mutex_lock(&cs);}
117
118inline void UnLock() {pthread_mutex_unlock(&cs);}
119
120enum MutexType {Simple = 0, Recursive = 1};
121
123 {int rc;
124 if (mt == Simple) rc = pthread_mutex_init(&cs, NULL);
125 else {pthread_mutexattr_t attr;
126 if (!(rc = pthread_mutexattr_init(&attr)))
127 {pthread_mutexattr_settype(&attr,
128 PTHREAD_MUTEX_RECURSIVE);
129 rc = pthread_mutex_init(&cs, &attr);
130 }
131 }
132 if (rc) throw strerror(rc);
133 }
134
135 ~XrdSsiMutex() {pthread_mutex_destroy(&cs);}
136
137protected:
138
139pthread_mutex_t cs;
140};
141
142/******************************************************************************/
143/* X r d S s i M u t e x M o n */
144/******************************************************************************/
145
147{
148public:
149
150inline void Lock(XrdSsiMutex *mutex)
151 {if (mtx) {if (mtx != mutex) mtx->UnLock();
152 else return;
153 }
154 mutex->Lock();
155 mtx = mutex;
156 };
157
158inline void Lock(XrdSsiMutex &mutex) {Lock(&mutex);}
159
160inline void UnLock() {if (mtx) {mtx->UnLock(); mtx = 0;}}
161
163 {if (mutex) mutex->Lock();
164 mtx = mutex;
165 }
167 {mutex.Lock();
168 mtx = &mutex;
169 }
170
172private:
174};
175#endif
Definition: XrdSsiAtomics.hh:147
XrdSsiMutexMon(XrdSsiMutex &mutex)
Definition: XrdSsiAtomics.hh:166
~XrdSsiMutexMon()
Definition: XrdSsiAtomics.hh:171
void Lock(XrdSsiMutex &mutex)
Definition: XrdSsiAtomics.hh:158
XrdSsiMutex * mtx
Definition: XrdSsiAtomics.hh:173
XrdSsiMutexMon(XrdSsiMutex *mutex=0)
Definition: XrdSsiAtomics.hh:162
void UnLock()
Definition: XrdSsiAtomics.hh:160
void Lock(XrdSsiMutex *mutex)
Definition: XrdSsiAtomics.hh:150
Definition: XrdSsiAtomics.hh:111
void UnLock()
Definition: XrdSsiAtomics.hh:118
MutexType
Definition: XrdSsiAtomics.hh:120
@ Recursive
Definition: XrdSsiAtomics.hh:120
@ Simple
Definition: XrdSsiAtomics.hh:120
XrdSsiMutex(MutexType mt=Simple)
Definition: XrdSsiAtomics.hh:122
bool TryLock()
Definition: XrdSsiAtomics.hh:114
void Lock()
Definition: XrdSsiAtomics.hh:116
~XrdSsiMutex()
Definition: XrdSsiAtomics.hh:135
pthread_mutex_t cs
Definition: XrdSsiAtomics.hh:139