xrootd
Loading...
Searching...
No Matches
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 <cstring>
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/* X r d S s i M u t e x */
105/******************************************************************************/
106
107#include <pthread.h>
108
110{
111public:
112
113inline bool TryLock() {return pthread_mutex_trylock( &cs ) == 0;}
114
115inline void Lock() {pthread_mutex_lock(&cs);}
116
117inline void UnLock() {pthread_mutex_unlock(&cs);}
118
119enum MutexType {Simple = 0, Recursive = 1};
120
122 {int rc;
123 if (mt == Simple) rc = pthread_mutex_init(&cs, NULL);
124 else {pthread_mutexattr_t attr;
125 if (!(rc = pthread_mutexattr_init(&attr)))
126 {pthread_mutexattr_settype(&attr,
127 PTHREAD_MUTEX_RECURSIVE);
128 rc = pthread_mutex_init(&cs, &attr);
129 }
130 }
131 if (rc) throw Errno2Text(rc);
132 }
133
134 ~XrdSsiMutex() {pthread_mutex_destroy(&cs);}
135
136protected:
137
138pthread_mutex_t cs;
139
140private:
141const char* Errno2Text(int ecode);
142};
143
144/******************************************************************************/
145/* X r d S s i M u t e x M o n */
146/******************************************************************************/
147
149{
150public:
151
152inline void Lock(XrdSsiMutex *mutex)
153 {if (mtx) {if (mtx != mutex) mtx->UnLock();
154 else return;
155 }
156 mutex->Lock();
157 mtx = mutex;
158 };
159
160inline void Lock(XrdSsiMutex &mutex) {Lock(&mutex);}
161
162inline void Reset() {mtx = 0;}
163
164inline void UnLock() {if (mtx) {mtx->UnLock(); mtx = 0;}}
165
167 {if (mutex) mutex->Lock();
168 mtx = mutex;
169 }
171 {mutex.Lock();
172 mtx = &mutex;
173 }
174
176private:
178};
179#endif
Definition XrdSsiAtomics.hh:149
XrdSsiMutexMon(XrdSsiMutex &mutex)
Definition XrdSsiAtomics.hh:170
~XrdSsiMutexMon()
Definition XrdSsiAtomics.hh:175
void Lock(XrdSsiMutex &mutex)
Definition XrdSsiAtomics.hh:160
XrdSsiMutex * mtx
Definition XrdSsiAtomics.hh:177
XrdSsiMutexMon(XrdSsiMutex *mutex=0)
Definition XrdSsiAtomics.hh:166
void UnLock()
Definition XrdSsiAtomics.hh:164
void Lock(XrdSsiMutex *mutex)
Definition XrdSsiAtomics.hh:152
void Reset()
Definition XrdSsiAtomics.hh:162
Definition XrdSsiAtomics.hh:110
void UnLock()
Definition XrdSsiAtomics.hh:117
MutexType
Definition XrdSsiAtomics.hh:119
@ Recursive
Definition XrdSsiAtomics.hh:119
@ Simple
Definition XrdSsiAtomics.hh:119
XrdSsiMutex(MutexType mt=Simple)
Definition XrdSsiAtomics.hh:121
bool TryLock()
Definition XrdSsiAtomics.hh:113
void Lock()
Definition XrdSsiAtomics.hh:115
const char * Errno2Text(int ecode)
~XrdSsiMutex()
Definition XrdSsiAtomics.hh:134
pthread_mutex_t cs
Definition XrdSsiAtomics.hh:138