add more lock primitives
authorbdemsky <bdemsky>
Thu, 15 Oct 2009 05:32:29 +0000 (05:32 +0000)
committerbdemsky <bdemsky>
Thu, 15 Oct 2009 05:32:29 +0000 (05:32 +0000)
Robust/src/Runtime/STM/stm.c
Robust/src/Runtime/STM/stmlock.c
Robust/src/Runtime/STM/stmlock.h

index 653945121a21f42fb701490f06b364d97307953c..45e4dd4cf577433b49efed386c65b6d3f1861054 100644 (file)
@@ -98,7 +98,7 @@ objheader_t *transCreateObj(void * ptr, unsigned int size) {
   objheader_t *tmp = mygcmalloc(ptr, (sizeof(objheader_t) + size));
 #endif
   objheader_t *retval=tmp+1;
-  tmp->lock=RW_LOCK_BIAS;
+  tmp->lock=SWAP_LOCK_BIAS;
   tmp->version = 1;
   //initialize obj lock to the header
   STATUS(tmp)=NEW;
index 971f90262c7f16d04798f541a2f9d62150a4d4f6..05079c15c7a880b8250f97a43d4d1ade52311843 100644 (file)
@@ -3,7 +3,7 @@
 
 
 inline void initdsmlocks(volatile unsigned int *addr) {
-  (*addr) = RW_LOCK_BIAS;
+  (*addr) = SWAP_LOCK_BIAS;
 }
 
 /*
@@ -15,9 +15,9 @@ int write_trylock(volatile unsigned int *lock) {
               : "memory");
   return retval;
 }
-*/
+
 
 void write_unlock(volatile unsigned int *lock) {
   __asm __volatile__("movl $1, %0" : "+m" (*lock)::"memory");
 }
-
+*/
index a396d8a530b9ef75e613f7b19b105b50b06f77a1..acc5f915925670d40495f291c640f70ff040ae73 100644 (file)
@@ -1,25 +1,28 @@
 #ifndef _STMLOCK_H_
 #define _STMLOCK_H_
 
-#define RW_LOCK_BIAS                 1
-#define LOCK_UNLOCKED          { LOCK_BIAS }
+#define SWAP_LOCK_BIAS                 1
 #define CFENCE   asm volatile("":::"memory");
 
-struct __xchg_dummy {
-       unsigned long a[100];
-};
+#define RW_LOCK_BIAS             0x01000000
 
-#define __xg(x) ((struct __xchg_dummy *)(x))
+#define LOCK_PREFIX \
+  ".section .smp_locks,\"a\"\n"   \
+  "  .align 4\n"                  \
+  "  .long 661f\n"             /* address */\
+  ".previous\n"                   \
+  "661:\n\tlock; "
 
 void initdsmlocks(volatile unsigned int *addr);
 //int write_trylock(volatile unsigned int *lock);
-void write_unlock(volatile unsigned int *lock);
+//void write_unlock(volatile unsigned int *lock);
 
 /*
 static inline void initdsmlocks(volatile unsigned int *addr) {
   (*addr) = RW_LOCK_BIAS;
 }
 */
+
 static inline int write_trylock(volatile unsigned int *lock) {
   int retval=0;
   __asm__ __volatile__("xchgl %0,%1"
@@ -29,10 +32,60 @@ static inline int write_trylock(volatile unsigned int *lock) {
   return retval;
 }
 
-/*
 static inline void write_unlock(volatile unsigned int *lock) {
-  __asm __volatile__("movl $1, %0" : "+m" (*__xg(lock))::"memory");
+  __asm__ __volatile__("movl $1, %0" : "+m" (*lock)::"memory");
+}
+
+
+static inline void atomic_add(int i, unsigned int *v) {
+  __asm__ __volatile__ (LOCK_PREFIX "addl %1,%0"
+                        : "+m" (*v)
+                        : "ir" (i));
 }
-*/
 
+static inline void read_unlock(volatile unsigned int *rw) {
+  __asm__ __volatile__ (LOCK_PREFIX "incl %0" : "+m" (*rw) : : "memory");
+}
+
+static inline void write_unlock(volatile unsigned int *rw) {
+  __asm__ __volatile__ (LOCK_PREFIX "addl %1, %0"
+                        : "+m" (*rw) : "i" (RW_LOCK_BIAS) : "memory");
+}
+
+static inline void atomic_dec(volatile unsigned int *v) {
+  __asm__ __volatile__ (LOCK_PREFIX "decl %0"
+                        : "+m" (*v));
+}
+
+static inline void atomic_inc(volatile unsigned int *v) {
+  __asm__ __volatile__ (LOCK_PREFIX "incl %0"
+                        : "+m" (*v));
+}
+
+static inline int atomic_sub_and_test(int i, unsigned int *v) {
+  unsigned char c;
+
+  __asm__ __volatile__ (LOCK_PREFIX "subl %2,%0; sete %1"
+                        : "+m" (*v), "=qm" (c)
+                        : "ir" (i) : "memory");
+  return c;
+}
+
+#define atomic_read(v)          (*v)
+
+static inline int read_trylock(volatile unsigned int  *lock) {
+  atomic_dec(lock);
+  if (atomic_read(lock) >= 0)
+    return 1; //can aquire a new read lock
+  atomic_inc(lock);
+  return 0; //failure
+}
+
+static inline int write_trylock(volatile unsigned int  *lock) {
+  if (atomic_sub_and_test(RW_LOCK_BIAS, *lock)) {
+    return 1; // get a write lock
+  }
+  atomic_add(RW_LOCK_BIAS, *lock);
+  return 0; // failed to acquire a write lock
+}
 #endif