From 959cbe93cdc3c0f7a3e8340c86f53db488e25aa1 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 2 Nov 2012 18:41:30 -0700 Subject: [PATCH 1/1] linuxrwlocks: add linux locks test --- Makefile | 2 +- linuxrwlocks/.gitignore | 1 + linuxrwlocks/Makefile | 11 ++++ linuxrwlocks/linuxrwlocks.c | 112 ++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 linuxrwlocks/.gitignore create mode 100644 linuxrwlocks/Makefile create mode 100644 linuxrwlocks/linuxrwlocks.c diff --git a/Makefile b/Makefile index e5ff6cc..9e102ec 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -DIRS := barrier mcs-lock mpmc-queue spsc-queue +DIRS := barrier mcs-lock mpmc-queue spsc-queue linuxrwlocks .PHONY: $(DIRS) diff --git a/linuxrwlocks/.gitignore b/linuxrwlocks/.gitignore new file mode 100644 index 0000000..2fdb632 --- /dev/null +++ b/linuxrwlocks/.gitignore @@ -0,0 +1 @@ +/linuxrwlocks diff --git a/linuxrwlocks/Makefile b/linuxrwlocks/Makefile new file mode 100644 index 0000000..d66ada3 --- /dev/null +++ b/linuxrwlocks/Makefile @@ -0,0 +1,11 @@ +include ../benchmarks.mk + +TESTNAME = linuxrwlocks + +all: $(TESTNAME) + +$(TESTNAME): $(TESTNAME).c + $(CC) -o $@ $< $(CPPFLAGS) $(LDFLAGS) + +clean: + rm -f $(TESTNAME) *.o diff --git a/linuxrwlocks/linuxrwlocks.c b/linuxrwlocks/linuxrwlocks.c new file mode 100644 index 0000000..7e317aa --- /dev/null +++ b/linuxrwlocks/linuxrwlocks.c @@ -0,0 +1,112 @@ +#include +#include +#include + +#include "librace.h" + +#define RW_LOCK_BIAS 0x00100000 +#define WRITE_LOCK_CMP RW_LOCK_BIAS + +/** Example implementation of linux rw lock along with 2 thread test + * driver... */ + +typedef union { + atomic_int lock; +} rwlock_t; + +static inline int read_can_lock(rwlock_t *lock) +{ + return atomic_load_explicit(&lock->lock, memory_order_relaxed) > 0; +} + +static inline int write_can_lock(rwlock_t *lock) +{ + return atomic_load_explicit(&lock->lock, memory_order_relaxed) == RW_LOCK_BIAS; +} + +static inline void read_lock(rwlock_t *rw) +{ + int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire); + while (priorvalue <= 0) { + atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed); + do { + priorvalue = atomic_load_explicit(&rw->lock, memory_order_relaxed); + } while (priorvalue <= 0); + priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire); + } +} + +static inline void write_lock(rwlock_t *rw) +{ + int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire); + while (priorvalue != RW_LOCK_BIAS) { + atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed); + do { + priorvalue = atomic_load_explicit(&rw->lock, memory_order_relaxed); + } while (priorvalue != RW_LOCK_BIAS); + priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire); + } +} + +static inline int read_trylock(rwlock_t *rw) +{ + int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire); + if (priorvalue > 0) + return 1; + + atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed); + return 0; +} + +static inline int write_trylock(rwlock_t *rw) +{ + int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire); + if (priorvalue == RW_LOCK_BIAS) + return 1; + + atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed); + return 0; +} + +static inline void read_unlock(rwlock_t *rw) +{ + atomic_fetch_add_explicit(&rw->lock, 1, memory_order_release); +} + +static inline void write_unlock(rwlock_t *rw) +{ + atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_release); +} + +rwlock_t mylock; +int shareddata; + +static void a(void *obj) +{ + int i; + for(i = 0; i < 2; i++) { + if ((i % 2) == 0) { + read_lock(&mylock); + load_32(&shareddata); + read_unlock(&mylock); + } else { + write_lock(&mylock); + store_32(&shareddata,(unsigned int)i); + write_unlock(&mylock); + } + } +} + +int user_main(int argc, char **argv) +{ + thrd_t t1, t2; + atomic_init(&mylock.lock, RW_LOCK_BIAS); + + thrd_create(&t1, (thrd_start_t)&a, NULL); + thrd_create(&t2, (thrd_start_t)&a, NULL); + + thrd_join(t1); + thrd_join(t2); + + return 0; +} -- 2.34.1