From c368a66eea791b5bd74165afe66e92d68092ce09 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Thu, 15 Oct 2009 05:32:29 +0000 Subject: [PATCH] add more lock primitives --- Robust/src/Runtime/STM/stm.c | 2 +- Robust/src/Runtime/STM/stmlock.c | 6 +-- Robust/src/Runtime/STM/stmlock.h | 73 +++++++++++++++++++++++++++----- 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/Robust/src/Runtime/STM/stm.c b/Robust/src/Runtime/STM/stm.c index 65394512..45e4dd4c 100644 --- a/Robust/src/Runtime/STM/stm.c +++ b/Robust/src/Runtime/STM/stm.c @@ -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; diff --git a/Robust/src/Runtime/STM/stmlock.c b/Robust/src/Runtime/STM/stmlock.c index 971f9026..05079c15 100644 --- a/Robust/src/Runtime/STM/stmlock.c +++ b/Robust/src/Runtime/STM/stmlock.c @@ -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"); } - +*/ diff --git a/Robust/src/Runtime/STM/stmlock.h b/Robust/src/Runtime/STM/stmlock.h index a396d8a5..acc5f915 100644 --- a/Robust/src/Runtime/STM/stmlock.h +++ b/Robust/src/Runtime/STM/stmlock.h @@ -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 -- 2.34.1