MADNESS  0.10.1
bgq_atomics.h
Go to the documentation of this file.
1 /*
2  * Written by Jeff Hammond, July 2012
3  * Copyright Argonne National Laboratory
4  *
5  * This implementation of BGQ atomics is based upon
6  * hwi/include/bqc/A2_inlines.h but uses signed integers
7  * instead of unsigned integer and/or long types.
8  *
9  * In theory, this should work for any PowerPC system. Need to verify on Blue Gene/P and POWER7.
10  */
11 
12 #include <stdint.h>
13 
14 #ifndef __INLINE__
15 #define __INLINE__ extern inline __attribute__((always_inline))
16 #endif
17 
18 /* Not yet verified for use on non-BGQ PPC but not active there anyways */
19 #if defined(__bgq__) || defined(__bgp__) || defined(__powerpc__)
20 __INLINE__ int32_t LoadReservedSigned32( volatile int32_t *pVar )
21 {
22  register int32_t Val;
23  asm volatile ("lwarx %[rc],0,%[pVar];"
24  : [rc] "=&b" (Val)
25  : [pVar] "b" (pVar));
26  return(Val);
27 }
28 
29 __INLINE__ int StoreConditionalSigned32( volatile int32_t *pVar, int32_t Val )
30 {
31  register int rc = 1; // assume success
32  asm volatile (" stwcx. %2,0,%1;"
33  " beq 1f;" // conditional store succeeded
34  " li %0,0;"
35  "1:;"
36  : "=b" (rc)
37  : "b" (pVar),
38  "b" (Val),
39  "0" (rc)
40  : "cc", "memory" );
41  return(rc);
42 }
43 
44 __INLINE__ int32_t CompareAndSwapSigned32( volatile int32_t *var, int32_t Compare, int32_t NewValue )
45 {
46  asm volatile ("msync" : : : "memory");
47 
48  int32_t OldValue = *var;
49 
50  do {
51  int32_t TmpValue = LoadReservedSigned32( var );
52  if ( Compare != TmpValue ) return(OldValue);
53  }
54  while( !StoreConditionalSigned32( var, NewValue ) );
55 
56  return(OldValue);
57 }
58 
59 __INLINE__ int32_t FetchAndAddSigned32( volatile int32_t *pVar, int32_t value )
60 {
61  asm volatile ("msync" : : : "memory");
62 
63  register int32_t old_val, tmp_val;
64 
65  do
66  {
67  old_val = LoadReservedSigned32( pVar );
68  tmp_val = old_val + value;
69  }
70  while ( !StoreConditionalSigned32( pVar, tmp_val ) );
71 
72  return( old_val );
73 }
74 
75 __INLINE__ void MemoryBarrier(void)
76 {
77  asm volatile ("msync" : : : "memory");
78 
79  return;
80 }
81 
82 #else
83 #error You cannot use PowerPC assembly on a non-PowerPC architecture!
84 #endif
#define __INLINE__
Definition: bgq_atomics.h:15