MADNESS  version 0.9
atomicint.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31  $Id$
32 */
33 #ifndef MADNESS_WORLD_ATOMICINT_H__INCLUDED
34 #define MADNESS_WORLD_ATOMICINT_H__INCLUDED
35 
37 
39 
40 #include <madness/madness_config.h>
41 
42 #if defined(HAVE_IBMBGP) && !defined(MADATOMIC_USE_GCC)
43 # define MADATOMIC_USE_BGP
44 #elif defined(HAVE_IBMBGQ)
45 # define MADATOMIC_USE_BGQ
46 #elif defined(USE_X86_32_ASM) || defined(USE_X86_64_ASM) || defined(X86_64) || defined(X86_32)
47 # define MADATOMIC_USE_X86_ASM
48 #else
49 # define MADATOMIC_USE_GCC
50 #endif
51 
52 #if defined(MADATOMIC_USE_BGP)
53 # include <bpcore/bgp_atomic_ops.h>
54 #elif defined (MADATOMIC_USE_BGQ)
55 # include "bgq_atomics.h"
56 #elif defined(MADATOMIC_USE_AIX)
57 # include <sys/atomic_op.h>
58 #elif defined(MADATOMIC_USE_GCC)
59 # ifdef GCC_ATOMICS_IN_BITS
60 # include <bits/atomicity.h>
61 # else
62 # include <ext/atomicity.h>
63 # endif
64 #endif
65 
66 namespace madness {
67 
69 
73  class AtomicInt {
74  private:
75 
76 #if defined(MADATOMIC_USE_BGP)
77  typedef _BGP_Atomic atomic_int;
78 #elif defined(MADATOMIC_USE_BGQ)
79  typedef volatile int atomic_int;
80 #else
81  typedef volatile int atomic_int;
82 #endif
83  atomic_int value;
84 
85  inline int exchange_and_add(int i) {
86 #if defined(MADATOMIC_USE_GCC)
87  return __gnu_cxx::__exchange_and_add(&value,i);
88 #elif defined(MADATOMIC_USE_X86_ASM)
89  __asm__ __volatile__("lock; xaddl %0,%1" :"=r"(i) : "m"(value), "0"(i));
90  return i;
91 #elif defined(MADATOMIC_USE_AIX)
92  return fetch_and_add(&value,i);
93 #elif defined(MADATOMIC_USE_BGP)
94  return _bgp_fetch_and_add(&value,i);
95 #elif defined(MADATOMIC_USE_BGQ)
96  return FetchAndAddSigned32(&value,i);
97 #else
98 # error ... atomic exchange_and_add operator must be implemented for this platform;
99 #endif
100  }
101 
102  public:
104  operator int() const volatile {
105  /* Jeff moved the memory barrier inside of the architecture-specific blocks
106  * since it may be required to use a heavier hammer on some of them. */
107 #if defined(MADATOMIC_USE_BGP)
108  int result = value.atom;
109  __asm__ __volatile__ ("" : : : "memory");
110  return result;
111 #elif defined (MADATOMIC_USE_BGQ)
112  int result = value;
113  __asm__ __volatile__ ("" : : : "memory");
114  return result;
115 #else
116  int result = value;
117  // BARRIER to stop instructions migrating up
118  __asm__ __volatile__ ("" : : : "memory");
119  return result;
120 #endif
121  }
122 
124  int operator=(int other) {
125  /* Jeff moved the memory barrier inside of the architecture-specific blocks
126  * since it may be required to use a heavier hammer on some of them. */
127 #if defined(MADATOMIC_USE_BGP)
128  // BARRIER to stop instructions migrating down
129  __asm__ __volatile__ ("" : : : "memory");
130  value.atom = other;
131 #elif defined (MADATOMIC_USE_BGQ)
132  __asm__ __volatile__ ("" : : : "memory");
133  value = other;
134 #else
135  __asm__ __volatile__ ("" : : : "memory");
136  value = other;
137 #endif
138  return other;
139  }
140 
142  AtomicInt& operator=(const AtomicInt& other) {
143  *this = int(other);
144  return *this;
145  }
146 
148  int operator--(int) {
149  return exchange_and_add(-1);
150  }
151 
153  int operator--() {
154  return exchange_and_add(-1) - 1;
155  }
156 
158  int operator++(int) {
159  return exchange_and_add(1);
160  }
161 
163  int operator++() {
164  return exchange_and_add(1) + 1;
165  }
166 
168  int operator+=(const int value) {
169  return exchange_and_add(value) + value;
170  }
171 
173  int operator-=(const int value) {
174  return exchange_and_add(-value) - value;
175  }
176 
178  bool dec_and_test() {
179  return ((*this)-- == 1);
180  }
181 
182 #ifdef ATOMICINT_CAS
183 
186  inline int compare_and_swap(int compare, int newval) {
187 #if defined(MADATOMIC_USE_GCC)
188  return __sync_val_compare_and_swap(&value, compare, newval);
189 #elif defined(MADATOMIC_USE_BGP)
190  return _bgp_compare_and_swap(&value, compare, newval);
191 #elif defined(MADATOMIC_USE_BGQ)
192  return CompareAndSwapSigned32(&value, compare, newval);
193 #else
194 #error ... atomic exchange_and_add operator must be implemented for this platform;
195 #endif
196  }
197 #endif
198 
199  }; // class AtomicInt
200 
201 }
202 #endif // MADNESS_WORLD_ATOMICINT_H__INCLUDED
int operator--(int)
Decrements the counter and returns the original value.
Definition: atomicint.h:148
int operator--()
Decrements the counter and returns the incremented value.
Definition: atomicint.h:153
int operator=(int other)
Sets the value of the counter with fence ensuring preceding operations are not moved after the store...
Definition: atomicint.h:124
bool dec_and_test()
Decrements the counter and returns true if the new value is zero.
Definition: atomicint.h:178
int operator++()
Increments the counter and returns the incremented value.
Definition: atomicint.h:163
AtomicInt & operator=(const AtomicInt &other)
Sets the value of the counter with fences ensuring operations are not moved either side of the load+s...
Definition: atomicint.h:142
int operator++(int)
Increments the counter and returns the original value.
Definition: atomicint.h:158
An integer with atomic set, get, read+inc, read+dec, dec+test operations.
Definition: atomicint.h:73
int operator-=(const int value)
Subtract value and returns the new value.
Definition: atomicint.h:173
int operator+=(const int value)
Add value and returns the new value.
Definition: atomicint.h:168
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45