From 512bbc050bb8d42ec9463dbc49eb90dc6ecb3ad4 Mon Sep 17 00:00:00 2001 From: Samy Al Bahra Date: Sun, 8 Jul 2012 15:59:30 -0400 Subject: [PATCH] ck_rwlock: Add recursive trylock operations. Unlike ck_rwlock, there is no spin factor associated with these. --- include/ck_rwlock.h | 29 +++++++++++++++++++++++ regressions/ck_rwlock/validate/validate.c | 25 ++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/include/ck_rwlock.h b/include/ck_rwlock.h index 804112d..1bd4372 100644 --- a/include/ck_rwlock.h +++ b/include/ck_rwlock.h @@ -192,6 +192,28 @@ leave: return; } +CK_CC_INLINE static bool +ck_rwlock_recursive_write_trylock(ck_rwlock_recursive_t *rw, unsigned int tid) +{ + unsigned int o; + + o = ck_pr_load_uint(&rw->rw.writer); + if (o == tid) + goto leave; + + if (ck_pr_cas_uint(&rw->rw.writer, 0, tid) == false) + return false; + + if (ck_pr_load_uint(&rw->rw.n_readers) != 0) { + ck_pr_store_uint(&rw->rw.writer, 0); + return false; + } + +leave: + rw->wc++; + return true; +} + CK_CC_INLINE static void ck_rwlock_recursive_write_unlock(ck_rwlock_recursive_t *rw) { @@ -210,6 +232,13 @@ ck_rwlock_recursive_read_lock(ck_rwlock_recursive_t *rw) return; } +CK_CC_INLINE static bool +ck_rwlock_recursive_read_trylock(ck_rwlock_recursive_t *rw) +{ + + return ck_rwlock_read_trylock(&rw->rw, 1); +} + CK_CC_INLINE static void ck_rwlock_recursive_read_unlock(ck_rwlock_recursive_t *rw) { diff --git a/regressions/ck_rwlock/validate/validate.c b/regressions/ck_rwlock/validate/validate.c index a944021..d51864a 100644 --- a/regressions/ck_rwlock/validate/validate.c +++ b/regressions/ck_rwlock/validate/validate.c @@ -64,10 +64,22 @@ thread_recursive(void *null CK_CC_UNUSED) } while (i--) { + if ((i % 10000) == 0) { + while (ck_rwlock_recursive_write_trylock(&r_lock, t) == false) + ck_pr_stall(); + } else { + ck_rwlock_recursive_write_lock(&r_lock, t); + } + ck_rwlock_recursive_write_lock(&r_lock, t); ck_rwlock_recursive_write_lock(&r_lock, t); ck_rwlock_recursive_write_lock(&r_lock, t); - ck_rwlock_recursive_write_lock(&r_lock, t); + + if (ck_rwlock_recursive_write_trylock(&r_lock, t) == false) { + fprintf(stderr, "ERROR: write_trylock failed.\n"); + exit(EXIT_FAILURE); + } + { l = ck_pr_load_uint(&locked); if (l != 0) { @@ -109,7 +121,16 @@ thread_recursive(void *null CK_CC_UNUSED) ck_rwlock_recursive_write_unlock(&r_lock); ck_rwlock_recursive_write_unlock(&r_lock); ck_rwlock_recursive_write_unlock(&r_lock); + ck_rwlock_recursive_write_unlock(&r_lock); + + if ((i % 10000) == 0) { + while (ck_rwlock_recursive_read_trylock(&r_lock) == false) + ck_pr_stall(); + } else { + ck_rwlock_recursive_read_lock(&r_lock); + } + ck_rwlock_recursive_read_lock(&r_lock); ck_rwlock_recursive_read_lock(&r_lock); { l = ck_pr_load_uint(&locked); @@ -119,6 +140,8 @@ thread_recursive(void *null CK_CC_UNUSED) } } ck_rwlock_recursive_read_unlock(&r_lock); + ck_rwlock_recursive_read_unlock(&r_lock); + ck_rwlock_recursive_read_unlock(&r_lock); } return (NULL);