// @(#)root/thread:$Id$
// Author: Fons Rademakers   14/11/06

/*************************************************************************
 * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TAtomicCountGcc
#define ROOT_TAtomicCountGcc


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TAtomicCountGcc                                                      //
//                                                                      //
// Class providing atomic operations on a long. Setting, getting,       //
// incrementing and decrementing are atomic, thread safe, operations.   //
//                                                                      //
// This implementation uses GNU libstdc++ v3 atomic primitives, see     //
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html.            //
//                                                                      //
// ATTENTION: Don't use this file directly, it is included by           //
//            TAtomicCount.h.                                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) || \
    (defined(__APPLE_CC__) && __APPLE_CC__ > 5000  && !defined(MAC_OS_X_VERSION_10_6))
#include <bits/atomicity.h>
#else
#include <ext/atomicity.h>
#endif

#if defined(__GLIBCXX__) // g++ 3.4+

using __gnu_cxx::__atomic_add;
using __gnu_cxx::__exchange_and_add;

#endif


class TAtomicCount {
private:
   mutable _Atomic_word fCnt;   // counter

   TAtomicCount(const TAtomicCount &);             // not implemented
   TAtomicCount &operator=(const TAtomicCount &);  // not implemented

public:
   explicit TAtomicCount(Long_t v) : fCnt(v) { }
   void operator++() { __atomic_add(&fCnt, 1); }
   Long_t operator--() { return __exchange_and_add(&fCnt, -1) - 1; }
   operator long() const { return __exchange_and_add(&fCnt, 0); }
   void Set(Long_t v) {
      fCnt = v;
#ifdef _GLIBCXX_WRITE_MEM_BARRIER
#if !(defined(__INTEL_COMPILER) && defined(__ia64__)) //ICC doesn't support inline asm on IA-64
      _GLIBCXX_WRITE_MEM_BARRIER;
#endif
#endif
   }
   Long_t Get() const { return __exchange_and_add(&fCnt, 0); }
};

#endif
 TAtomicCountGcc.h:1
 TAtomicCountGcc.h:2
 TAtomicCountGcc.h:3
 TAtomicCountGcc.h:4
 TAtomicCountGcc.h:5
 TAtomicCountGcc.h:6
 TAtomicCountGcc.h:7
 TAtomicCountGcc.h:8
 TAtomicCountGcc.h:9
 TAtomicCountGcc.h:10
 TAtomicCountGcc.h:11
 TAtomicCountGcc.h:12
 TAtomicCountGcc.h:13
 TAtomicCountGcc.h:14
 TAtomicCountGcc.h:15
 TAtomicCountGcc.h:16
 TAtomicCountGcc.h:17
 TAtomicCountGcc.h:18
 TAtomicCountGcc.h:19
 TAtomicCountGcc.h:20
 TAtomicCountGcc.h:21
 TAtomicCountGcc.h:22
 TAtomicCountGcc.h:23
 TAtomicCountGcc.h:24
 TAtomicCountGcc.h:25
 TAtomicCountGcc.h:26
 TAtomicCountGcc.h:27
 TAtomicCountGcc.h:28
 TAtomicCountGcc.h:29
 TAtomicCountGcc.h:30
 TAtomicCountGcc.h:31
 TAtomicCountGcc.h:32
 TAtomicCountGcc.h:33
 TAtomicCountGcc.h:34
 TAtomicCountGcc.h:35
 TAtomicCountGcc.h:36
 TAtomicCountGcc.h:37
 TAtomicCountGcc.h:38
 TAtomicCountGcc.h:39
 TAtomicCountGcc.h:40
 TAtomicCountGcc.h:41
 TAtomicCountGcc.h:42
 TAtomicCountGcc.h:43
 TAtomicCountGcc.h:44
 TAtomicCountGcc.h:45
 TAtomicCountGcc.h:46
 TAtomicCountGcc.h:47
 TAtomicCountGcc.h:48
 TAtomicCountGcc.h:49
 TAtomicCountGcc.h:50
 TAtomicCountGcc.h:51
 TAtomicCountGcc.h:52
 TAtomicCountGcc.h:53
 TAtomicCountGcc.h:54
 TAtomicCountGcc.h:55
 TAtomicCountGcc.h:56
 TAtomicCountGcc.h:57
 TAtomicCountGcc.h:58
 TAtomicCountGcc.h:59
 TAtomicCountGcc.h:60
 TAtomicCountGcc.h:61
 TAtomicCountGcc.h:62
 TAtomicCountGcc.h:63
 TAtomicCountGcc.h:64
 TAtomicCountGcc.h:65
 TAtomicCountGcc.h:66
 TAtomicCountGcc.h:67
 TAtomicCountGcc.h:68
 TAtomicCountGcc.h:69