buildscript options to enable exaclty which coreprof events are needed, keeps instrum...
[IRC.git] / Robust / src / Runtime / mlp_lock.h
1 #ifndef ____MLP_LOCK_H__
2 #define ____MLP_LOCK_H__
3
4
5 #include "runtime.h"
6
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <assert.h>
10
11 #define __xg(x) ((volatile INTPTR *)(x))
12
13 #define CFENCE   asm volatile("":::"memory");
14
15 #define LOCK_PREFIX \
16   ".section .smp_locks,\"a\"\n"   \
17   "  .align 4\n"                  \
18   "  .long 661f\n"             /* address */\
19   ".previous\n"                   \
20   "661:\n\tlock; "
21
22
23 static inline void atomic_dec(volatile int *v) {
24   __asm__ __volatile__ (LOCK_PREFIX "decl %0"
25                         : "+m" (*v));
26 }
27
28 static inline void atomic_inc(volatile int *v) {
29   __asm__ __volatile__ (LOCK_PREFIX "incl %0"
30                         : "+m" (*v));
31 }
32
33 // this returns TRUE if the atomic subtraction results in
34 // a zero value--this way two threads cannot dec a value
35 // atomically, but then go ahead and both read zero,
36 // thinking they both are the last decrementer
37 static inline int atomic_sub_and_test(int i, volatile int *v) {
38   unsigned char c;
39
40   __asm__ __volatile__ (LOCK_PREFIX "subl %2,%0; sete %1"
41                         : "+m" (*v), "=qm" (c)
42                         : "ir" (i) : "memory");
43   return c;
44 }
45
46 #ifdef BIT64
47 static inline INTPTR LOCKXCHG(volatile INTPTR * ptr, INTPTR val){
48   INTPTR retval;
49   //note: xchgl always implies lock 
50   __asm__ __volatile__("xchgq %0,%1"
51                        : "=r"(retval)
52                        : "m"(*ptr), "0"(val)
53                        : "memory");
54   return retval;
55  
56 }
57 #else
58 static inline int LOCKXCHG(volatile int* ptr, int val){
59   int retval;
60   //note: xchgl always implies lock 
61   __asm__ __volatile__("xchgl %0,%1"
62                        : "=r"(retval)
63                        : "m"(*ptr), "0"(val)
64                        : "memory");
65   return retval;
66  
67 }
68 #endif
69
70 /*
71 static inline int write_trylock(volatile int *lock) {
72   int retval=0;
73   __asm__ __volatile__("xchgl %0,%1"
74                        : "=r"(retval)
75                        : "m"(*lock), "0"(retval)
76                        : "memory");
77   return retval;
78 }
79 */
80
81 #ifdef BIT64
82 static inline INTPTR CAS(volatile void *ptr, unsigned INTPTR old, unsigned INTPTR new){
83   unsigned INTPTR prev;
84   __asm__ __volatile__("lock; cmpxchgq %1,%2"
85                        : "=a"(prev)
86                        : "r"(new), "m"(*__xg(ptr)), "0"(old)
87                        : "memory");
88   return prev;
89 }
90 #else
91 static inline long CAS(volatile void *ptr, unsigned long old, unsigned long new){
92   unsigned long prev;
93   __asm__ __volatile__("lock; cmpxchgl %k1,%2"
94                        : "=a"(prev)
95                        : "r"(new), "m"(*__xg(ptr)), "0"(old)
96                        : "memory");
97   return prev;
98 }
99 #endif
100
101 static inline int BARRIER(){
102   CFENCE;
103   return 1;
104 }
105
106
107 #endif // ____MLP_LOCK_H__