diff --git a/include/ck_rwlock.h b/include/ck_rwlock.h index 0fc2013..73a1bd7 100644 --- a/include/ck_rwlock.h +++ b/include/ck_rwlock.h @@ -233,6 +233,7 @@ ck_rwlock_read_latchlock(ck_rwlock_t *rw) snapshot = ck_pr_load_32(&rw->n_readers); } while (snapshot >> CK_RWLOCK_LATCH_SHIFT); + ck_pr_cas_32(&rw->n_readers, snapshot + 1, snapshot); continue; } diff --git a/regressions/ck_rwlock/validate/Makefile b/regressions/ck_rwlock/validate/Makefile index 2c2116b..608416c 100644 --- a/regressions/ck_rwlock/validate/Makefile +++ b/regressions/ck_rwlock/validate/Makefile @@ -14,4 +14,4 @@ clean: rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) include ../../../build/regressions.build -CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE +CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE -O0 diff --git a/regressions/ck_rwlock/validate/validate.c b/regressions/ck_rwlock/validate/validate.c index de77d26..d19affd 100644 --- a/regressions/ck_rwlock/validate/validate.c +++ b/regressions/ck_rwlock/validate/validate.c @@ -333,6 +333,55 @@ thread_rtm(void *null CK_CC_UNUSED) } #endif /* CK_F_PR_RTM */ +static void * +thread_latch(void *null CK_CC_UNUSED) +{ + unsigned int i = ITERATE; + unsigned int l; + + if (aff_iterate(&a)) { + perror("ERROR: Could not affine thread"); + exit(EXIT_FAILURE); + } + + while (i--) { + ck_rwlock_write_lock(&lock); + ck_rwlock_write_latch(&lock); + { + ck_pr_inc_uint(&locked); + ck_pr_inc_uint(&locked); + ck_pr_inc_uint(&locked); + ck_pr_inc_uint(&locked); + ck_pr_inc_uint(&locked); + ck_pr_inc_uint(&locked); + ck_pr_inc_uint(&locked); + ck_pr_inc_uint(&locked); + + ck_pr_dec_uint(&locked); + ck_pr_dec_uint(&locked); + ck_pr_dec_uint(&locked); + ck_pr_dec_uint(&locked); + ck_pr_dec_uint(&locked); + ck_pr_dec_uint(&locked); + ck_pr_dec_uint(&locked); + ck_pr_dec_uint(&locked); + } + ck_rwlock_write_unlatch(&lock); + ck_rwlock_write_unlock(&lock); + + ck_rwlock_read_latchlock(&lock); + { + l = ck_pr_load_uint(&locked); + if (l != 0) { + ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l); + } + } + ck_rwlock_read_unlock(&lock); + } + + return (NULL); +} + static void * thread(void *null CK_CC_UNUSED) { @@ -436,6 +485,7 @@ main(int argc, char *argv[]) a.delta = atoi(argv[2]); rwlock_test(threads, thread, "regular"); + rwlock_test(threads, thread_latch, "latch"); #ifdef CK_F_PR_RTM rwlock_test(threads, thread_rtm, "rtm"); rwlock_test(threads, thread_rtm_mix, "rtm-mix");