Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:15:42

0001 #ifndef _XRDSYSATOMICS_
0002 #define _XRDSYSATOMICS_
0003 /******************************************************************************/
0004 /*                                                                            */
0005 /*                      X r d S y s A t o m i c s . h h                       */
0006 /*                                                                            */
0007 /* (c) 2011 by the Board of Trustees of the Leland Stanford, Jr., University  */
0008 /*                            All Rights Reserved                             */
0009 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
0010 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
0011 /*                                                                            */
0012 /* This file is part of the XRootD software suite.                            */
0013 /*                                                                            */
0014 /* XRootD is free software: you can redistribute it and/or modify it under    */
0015 /* the terms of the GNU Lesser General Public License as published by the     */
0016 /* Free Software Foundation, either version 3 of the License, or (at your     */
0017 /* option) any later version.                                                 */
0018 /*                                                                            */
0019 /* XRootD is distributed in the hope that it will be useful, but WITHOUT      */
0020 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or      */
0021 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public       */
0022 /* License for more details.                                                  */
0023 /*                                                                            */
0024 /* You should have received a copy of the GNU Lesser General Public License   */
0025 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file  */
0026 /* COPYING (GPL license).  If not, see <http://www.gnu.org/licenses/>.        */
0027 /*                                                                            */
0028 /* The copyright holder's institutional names and contributor's names may not */
0029 /* be used to endorse or promote products derived from this software without  */
0030 /* specific prior written permission of the institution or contributor.       */
0031 /******************************************************************************/
0032 
0033 /* The following instruction acronyms are used:
0034    AtomicCAS() -> Compare And [if equal] Set
0035    AtomicFAZ() -> Fetch And Zero
0036 */
0037 
0038 /* Portability note: When using fetch-add or fetch-sub in the context of an
0039                      assignment statement, you must use the the AtomicFAdd
0040                      and AtomicFSub macros to ensure portability and correct
0041                      results. Additionally, whenever you use AtomicFAZ as the
0042                      only consequent of an if-else statement you *must* places
0043                      braces around it otherwise the code will not be portable!
0044                      Alternatively, always use the AtomicFZAP macro.
0045 */
0046   
0047 #ifdef HAVE_ATOMICS
0048 #define AtomicBeg(Mtx)
0049 #define AtomicEnd(Mtx)
0050 #define AtomicAdd(x, y)     __sync_fetch_and_add(&x, y)
0051 #define AtomicFAdd(w,x,y)   w =  __sync_fetch_and_add(&x, y)
0052 #define AtomicCAS(x, y, z)  __sync_bool_compare_and_swap(&x, y, z)
0053 #define AtomicDec(x)        __sync_fetch_and_sub(&x, 1)
0054 #define AtomicFAZ(x)        __sync_fetch_and_and(&x, 0)
0055 #define AtomicFZAP(w,x)     w =  __sync_fetch_and_and(&x, 0)
0056 #define AtomicGet(x)        __sync_fetch_and_or(&x, 0)
0057 #define AtomicInc(x)        __sync_fetch_and_add(&x, 1)
0058 #define AtomicSub(x, y)     __sync_fetch_and_sub(&x, y)
0059 #define AtomicFSub(w,x,y)   w =  __sync_fetch_and_sub(&x, y)
0060 #define AtomicZAP(x)        __sync_fetch_and_and(&x, 0)
0061 #define AtomicRet(mtx, x)   return AtomicGet(x)
0062 #else
0063 #define AtomicBeg(Mtx)      Mtx.Lock()
0064 #define AtomicEnd(Mtx)      Mtx.UnLock()
0065 #define AtomicAdd(x, y)     x += y          // When assigning use AtomicFAdd!
0066 #define AtomicFAdd(w,x,y)  {w = x; x += y;}
0067 #define AtomicCAS(x, y, z)  if (x == y) x = z
0068 #define AtomicDec(x)        x--
0069 #define AtomicFAZ(x)        x; x = 0        // Braces when used with if-else!
0070 #define AtomicFZAP(w,x)    {w = x; x = 0;}
0071 #define AtomicGet(x)        x
0072 #define AtomicInc(x)        x++
0073 #define AtomicSub(x, y)     x -= y          // When assigning use AtomicFSub!
0074 #define AtomicFSub(w,x,y)  {w = x; x -= y;}
0075 #define AtomicZAP(x)        x = 0
0076 #define AtomicRet(mtx, x)   {mtx.Lock(); int _ ## x = x; \
0077                              mtx.UnLock(); return _ ## x;}
0078 #endif
0079 #endif
0080 
0081 /*
0082  * The following definitions give a mechanism for using C++ atomics
0083  * (when using at least C++11).  *Note* that these can't be relied
0084  * on for correct behavior as they are non-atomic for C++03 compilers.
0085  *
0086  * Only use them for standards correctness (eliminating C++11 undefined
0087  * behavior).
0088  */
0089 #if __cplusplus >= 201103L
0090 #include <atomic>
0091 #define CPP_ATOMIC_LOAD(x, order)       x.load(order)
0092 #define CPP_ATOMIC_STORE(x, val, order) x.store(val, order)
0093 #define CPP_ATOMIC_TYPE(kind)           std::atomic<kind>
0094 #else
0095 #define CPP_ATOMIC_LOAD(x, order)       x
0096 #define CPP_ATOMIC_STORE(x, val, order) x = val
0097 #define CPP_ATOMIC_TYPE(kind)           kind
0098 #endif
0099 
0100