small rewrites
[IRC.git] / Robust / src / Runtime / DSTM / interface / dsmlock.c
1 #include "dsmlock.h"
2 #include <stdio.h>
3
4 inline void initdsmlocks(volatile unsigned int *addr) {
5   (*addr) = RW_LOCK_BIAS;
6 }
7
8
9 inline void readLock(volatile unsigned int *addr) {
10   __asm__ __volatile__ ("" " subl $1,(%0)\n\t"
11                         "jns 1f\n"
12                         "1:\n"
13                         :: "a" (addr) : "memory");
14 }
15
16 inline void writeLock(volatile unsigned int *addr) {
17   __asm__ __volatile__ ("" " subl %1,(%0)\n\t"
18                         "jz 1f\n"
19                         "1:\n"
20                         :: "a" (addr), "i" (RW_LOCK_BIAS) : "memory");
21 }
22
23 inline void atomic_dec(volatile unsigned int *v) {
24   __asm__ __volatile__ (LOCK_PREFIX "decl %0"
25                         : "+m" (v));
26 }
27
28 inline void atomic_inc(volatile unsigned int *v) {
29   __asm__ __volatile__ (LOCK_PREFIX "incl %0"
30                         : "+m" (v));
31 }
32
33 static inline int atomic_sub_and_test(int i, atomic_t *v) {
34   unsigned char c;
35
36   __asm__ __volatile__ (LOCK_PREFIX "subl %2,%0; sete %1"
37                         : "+m" (v->counter), "=qm" (c)
38                         : "ir" (i) : "memory");
39   return c;
40 }
41
42 /**
43  * atomic_add - add integer to atomic variable
44  * @i: integer value to add
45  * @v: pointer of type atomic_t
46  *
47  * Atomically adds @i to @v.
48  */
49 static inline void atomic_add(int i, atomic_t *v) {
50   __asm__ __volatile__ (LOCK_PREFIX "addl %1,%0"
51                         : "+m" (v->counter)
52                         : "ir" (i));
53 }
54
55 inline int read_trylock(volatile unsigned int  *lock) {
56   atomic_dec(lock);
57   if (atomic_read(lock) >= 0)
58     return 1; //can aquire a new read lock
59   atomic_inc(lock);
60   return 0; //failure
61 }
62
63 inline int write_trylock(volatile unsigned int  *lock) {
64   atomic_t *count = (atomic_t *)lock;
65   if (atomic_sub_and_test(RW_LOCK_BIAS, count)) {
66     return 1; // get a write lock
67   }
68   atomic_add(RW_LOCK_BIAS, count);
69   return 0; // failed to acquire a write lock
70 }
71
72 inline void read_unlock(volatile unsigned int *rw) {
73   __asm__ __volatile__ (LOCK_PREFIX "incl %0" : "+m" (*rw) : : "memory");
74 }
75
76 inline void write_unlock(volatile unsigned int *rw) {
77   __asm__ __volatile__ (LOCK_PREFIX "addl %1, %0"
78                         : "+m" (*rw) : "i" (RW_LOCK_BIAS) : "memory");
79 }