bug fixes
[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 static inline int LOCKXCHG32(volatile int* ptr, int val){
47   int retval;
48   //note: xchgl always implies lock 
49   __asm__ __volatile__("xchgl %0,%1"
50                        : "=r"(retval)
51                        : "m"(*ptr), "0"(val)
52                        : "memory");
53   return retval;
54  
55 }
56
57 #ifdef BIT64
58 static inline INTPTR LOCKXCHG(volatile INTPTR * ptr, INTPTR val){
59   INTPTR retval;
60   //note: xchgl always implies lock 
61   __asm__ __volatile__("xchgq %0,%1"
62                        : "=r"(retval)
63                        : "m"(*ptr), "0"(val)
64                        : "memory");
65   return retval;
66  
67 }
68 #else
69 #define LOCKXCHG LOCKXCHG32
70 #endif
71
72 /*
73 static inline int write_trylock(volatile int *lock) {
74   int retval=0;
75   __asm__ __volatile__("xchgl %0,%1"
76                        : "=r"(retval)
77                        : "m"(*lock), "0"(retval)
78                        : "memory");
79   return retval;
80 }
81 */
82
83 #ifdef BIT64
84 static inline INTPTR CAS(volatile void *ptr, unsigned INTPTR old, unsigned INTPTR new){
85   unsigned INTPTR prev;
86   __asm__ __volatile__("lock; cmpxchgq %1,%2"
87                        : "=a"(prev)
88                        : "r"(new), "m"(*__xg(ptr)), "0"(old)
89                        : "memory");
90   return prev;
91 }
92 #else
93 static inline long CAS(volatile void *ptr, unsigned long old, unsigned long new){
94   unsigned long prev;
95   __asm__ __volatile__("lock; cmpxchgl %k1,%2"
96                        : "=a"(prev)
97                        : "r"(new), "m"(*__xg(ptr)), "0"(old)
98                        : "memory");
99   return prev;
100 }
101 #endif
102
103 static inline int BARRIER(){
104   CFENCE;
105   return 1;
106 }
107
108
109 #endif // ____MLP_LOCK_H__