From 5e1b6141084624ce882152ad31944672018c2e9a Mon Sep 17 00:00:00 2001 From: Brendon Scheinman Date: Sat, 9 Mar 2013 19:24:22 -0600 Subject: [PATCH] ck_cohort_rw: Initial implementation with validation test. I still need to implement benchmark tests and write documentation. The reader-writer cohort locks also required that I add a method to the existing ck_cohort framework to determine whether or not a cohort lock is currently in a locked state. --- include/ck_cohort.h | 17 +- include/ck_cohort_rw.h | 142 +++++++++++++ regressions/ck_cohort_rw/ck_cohort.h | 25 +++ regressions/ck_cohort_rw/validate/Makefile | 17 ++ regressions/ck_cohort_rw/validate/validate | Bin 0 -> 30672 bytes regressions/ck_cohort_rw/validate/validate.c | 208 +++++++++++++++++++ 6 files changed, 405 insertions(+), 4 deletions(-) create mode 100644 include/ck_cohort_rw.h create mode 100644 regressions/ck_cohort_rw/ck_cohort.h create mode 100644 regressions/ck_cohort_rw/validate/Makefile create mode 100755 regressions/ck_cohort_rw/validate/validate create mode 100644 regressions/ck_cohort_rw/validate/validate.c diff --git a/include/ck_cohort.h b/include/ck_cohort.h index f82a251..9b14fb4 100644 --- a/include/ck_cohort.h +++ b/include/ck_cohort.h @@ -51,8 +51,9 @@ enum ck_cohort_state { #define CK_COHORT_LOCK(N, C, GC, LC) ck_cohort_##N##_lock(C, GC, LC) #define CK_COHORT_UNLOCK(N, C, GC, LC) ck_cohort_##N##_unlock(C, GC, LC) #define CK_COHORT_TRYLOCK(N, C, GLC, LLC, LUC) ck_cohort_##N##_trylock(C, GLC, LLC, LUC) +#define CK_COHORT_LOCKED(N, C, GC, LC) ck_cohort_##N##_locked(C, GC, LC) -#define CK_COHORT_PROTOTYPE(N, GL, GU, LL, LU) \ +#define CK_COHORT_PROTOTYPE(N, GL, GU, GI, LL, LU, LI) \ CK_COHORT_INSTANCE(N) { \ void *global_lock; \ void *local_lock; \ @@ -111,10 +112,18 @@ enum ck_cohort_state { LU(cohort->local_lock, local_context); \ \ return; \ + } \ + \ + CK_CC_INLINE static bool \ + ck_cohort_##N##_locked(CK_COHORT_INSTANCE(N) *cohort, \ + void *global_context, void *local_context) \ + { \ + return GI(cohort->local_lock, local_context) || \ + LI(cohort->global_lock, global_context); \ } -#define CK_COHORT_TRYLOCK_PROTOTYPE(N, GL, GU, GTL, LL, LU, LTL) \ - CK_COHORT_PROTOTYPE(N, GL, GU, LL, LU) \ +#define CK_COHORT_TRYLOCK_PROTOTYPE(N, GL, GU, GI, GTL, LL, LU, LI, LTL) \ + CK_COHORT_PROTOTYPE(N, GL, GU, GI, LL, LU, LI) \ CK_CC_INLINE static bool \ ck_cohort_##N##_trylock(CK_COHORT_INSTANCE(N) *cohort, \ void *global_context, void *local_context, \ @@ -132,7 +141,7 @@ enum ck_cohort_state { \ if (cohort->release_state == CK_COHORT_STATE_GLOBAL && \ GTL(cohort->global_lock, global_context) == false) { \ - LU(cohort->local_lock, local_unlock_context); \ + LU(cohort->local_lock, local_unlock_context); \ return false; \ } \ \ diff --git a/include/ck_cohort_rw.h b/include/ck_cohort_rw.h new file mode 100644 index 0000000..471377c --- /dev/null +++ b/include/ck_cohort_rw.h @@ -0,0 +1,142 @@ +/* + * Copyright 2013 Samy Al Bahra. + * Copyright 2013 Brendon Scheinman. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _CK_COHORT_RW_H +#define _CK_COHORT_RW_H + +/* + * This is an implementation of NUMA-aware reader-writer locks as described in: + * Calciu, I.; Dice, D.; Lev, Y.; Luchangco, V.; Marathe, V.; and Shavit, N. 2013. + * NUMA-Aware Reader-Writer Locks + */ + +#include +#include +#include +#include + +#define CK_COHORT_RW_NAME(N) ck_cohort_rw_##N +#define CK_COHORT_RW_INSTANCE(N) struct CK_COHORT_RW_NAME(N) +#define CK_COHORT_RW_INIT(N, RW, WL) ck_cohort_rw_##N##_init(RW, WL) +#define CK_COHORT_RW_READ_LOCK(N, RW, C, GC, LC) ck_cohort_rw_##N##_read_lock(RW, C, GC, LC) +#define CK_COHORT_RW_READ_UNLOCK(N, RW) ck_cohort_rw_##N##_read_unlock(RW) +#define CK_COHORT_RW_WRITE_LOCK(N, RW, C, GC, LC) ck_cohort_rw_##N##_write_lock(RW, C, GC, LC) +#define CK_COHORT_RW_WRITE_UNLOCK(N, RW, C, GC, LC) ck_cohort_rw_##N##_write_unlock(RW, C, GC, LC) +#define CK_COHORT_RW_DEFAULT_WAIT_LIMIT 1000 + +#define CK_COHORT_RW_PROTOTYPE(N) \ + CK_COHORT_RW_INSTANCE(N) { \ + CK_COHORT_INSTANCE(N) *cohort; \ + unsigned int read_counter; \ + unsigned int write_barrier; \ + unsigned int wait_limit; \ + }; \ + \ + CK_CC_INLINE static void \ + ck_cohort_rw_##N##_init(CK_COHORT_RW_INSTANCE(N) *rw_cohort, \ + unsigned int wait_limit) \ + { \ + rw_cohort->read_counter = 0; \ + rw_cohort->write_barrier = 0; \ + rw_cohort->wait_limit = wait_limit; \ + ck_pr_barrier(); \ + return; \ + } \ + \ + CK_CC_INLINE static void \ + ck_cohort_rw_##N##_write_lock(CK_COHORT_RW_INSTANCE(N) *rw_cohort, \ + CK_COHORT_INSTANCE(N) *cohort, void *global_context, \ + void *local_context) \ + { \ + while (ck_pr_load_uint(&rw_cohort->write_barrier) > 0) { \ + ck_pr_stall(); \ + } \ + \ + CK_COHORT_LOCK(N, cohort, global_context, local_context); \ + \ + while (ck_pr_load_uint(&rw_cohort->read_counter) > 0) { \ + ck_pr_stall(); \ + } \ + \ + return; \ + } \ + \ + CK_CC_INLINE static void \ + ck_cohort_rw_##N##_write_unlock(CK_COHORT_RW_INSTANCE(N) *rw_cohort, \ + CK_COHORT_INSTANCE(N) *cohort, void *global_context, \ + void *local_context) \ + { \ + (void)rw_cohort; \ + CK_COHORT_UNLOCK(N, cohort, global_context, local_context); \ + } \ + \ + CK_CC_INLINE static void \ + ck_cohort_rw_##N##_read_lock(CK_COHORT_RW_INSTANCE(N) *rw_cohort, \ + CK_COHORT_INSTANCE(N) *cohort, void *global_context, \ + void *local_context) \ + { \ + unsigned int wait_count = 0; \ + bool raised = false; \ + start: \ + ck_pr_inc_uint(&rw_cohort->read_counter); \ + if (CK_COHORT_LOCKED(N, cohort, global_context, local_context) \ + == true) { \ + ck_pr_dec_uint(&rw_cohort->read_counter); \ + while (CK_COHORT_LOCKED(N, cohort, global_context, \ + local_context) == true) { \ + ck_pr_stall(); \ + if (++wait_count > rw_cohort->wait_limit \ + && raised == false) { \ + ck_pr_inc_uint( \ + &rw_cohort->write_barrier); \ + raised = true; \ + } \ + } \ + goto start; \ + } \ + \ + if (raised == true) { \ + ck_pr_dec_uint(&rw_cohort->write_barrier); \ + } \ + \ + return; \ + } \ + \ + CK_CC_INLINE static void \ + ck_cohort_rw_##N##_read_unlock(CK_COHORT_RW_INSTANCE(N) *cohort) \ + { \ + ck_pr_dec_uint(&cohort->read_counter); \ + } + +#define CK_COHORT_RW_INITIALIZER { \ + .cohort = NULL, \ + .read_counter = 0, \ + .write_barrier = 0, \ + .wait_limit = 0 \ +} + +#endif /* _CK_COHORT_RW_H */ diff --git a/regressions/ck_cohort_rw/ck_cohort.h b/regressions/ck_cohort_rw/ck_cohort.h new file mode 100644 index 0000000..847544c --- /dev/null +++ b/regressions/ck_cohort_rw/ck_cohort.h @@ -0,0 +1,25 @@ +#define LOCK_NAME "ck_cohort" +#define LOCK_DEFINE\ + static ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\ + static ck_spinlock_fas_t local_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\ + static void\ + ck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)\ + {\ + (void)context;\ + ck_spinlock_fas_lock(lock);\ + }\ +\ + static void\ + ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)\ + {\ + (void)context;\ + ck_spinlock_fas_unlock(lock);\ + }\ + CK_COHORT_PROTOTYPE(fas_fas,\ + ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context,\ + ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context)\ + static CK_COHORT_INSTANCE(fas_fas) CK_CC_CACHELINE cohort = CK_COHORT_INITIALIZER +#define LOCK_INIT CK_COHORT_INIT(fas_fas, &cohort, &global_fas_lock, &local_fas_lock,\ + CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT) +#define LOCK CK_COHORT_LOCK(fas_fas, &cohort, NULL, NULL) +#define UNLOCK CK_COHORT_UNLOCK(fas_fas, &cohort, NULL, NULL) diff --git a/regressions/ck_cohort_rw/validate/Makefile b/regressions/ck_cohort_rw/validate/Makefile new file mode 100644 index 0000000..2582598 --- /dev/null +++ b/regressions/ck_cohort_rw/validate/Makefile @@ -0,0 +1,17 @@ +.PHONY: check clean distribution + +OBJECTS=validate + +all: $(OBJECTS) + +validate: validate.c ../../../include/ck_cohort_rw.h + $(CC) $(CFLAGS) -o validate validate.c -g + +check: all + ./validate $(CORES) 1 + +clean: + rm -rf *.dSYM *~ *.o $(OBJECTS) + +include ../../../build/regressions.build +CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_cohort_rw/validate/validate b/regressions/ck_cohort_rw/validate/validate new file mode 100755 index 0000000000000000000000000000000000000000..c8f46cc62658105cb8fa2762df7aa17aae1abb03 GIT binary patch literal 30672 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 AJOBUy literal 0 HcmV?d00001 diff --git a/regressions/ck_cohort_rw/validate/validate.c b/regressions/ck_cohort_rw/validate/validate.c new file mode 100644 index 0000000..4854f65 --- /dev/null +++ b/regressions/ck_cohort_rw/validate/validate.c @@ -0,0 +1,208 @@ +/* + * Copyright 2013 Samy Al Bahra. + * Copything 2013 Brendon Scheinman. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../../common.h" + +#ifndef ITERATE +#define ITERATE 1000000 +#endif + +static struct affinity a; +static unsigned int locked; +static int nthr; +static ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER; + +static void +ck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context) +{ + (void)context; + ck_spinlock_fas_lock(lock); +} + +static void +ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context) +{ + (void)context; + ck_spinlock_fas_unlock(lock); +} + +static bool +ck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context) +{ + (void)context; + return ck_spinlock_fas_locked(lock); +} + +CK_COHORT_PROTOTYPE(fas_fas, + ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context, + ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context) +CK_COHORT_RW_PROTOTYPE(fas_fas) + +static CK_COHORT_INSTANCE(fas_fas) *cohorts; +static CK_COHORT_RW_INSTANCE(fas_fas) rw_cohort = CK_COHORT_RW_INITIALIZER; +static int n_cohorts; + +static void * +thread(void *null CK_CC_UNUSED) +{ + int i = ITERATE; + unsigned int l; + unsigned int core; + CK_COHORT_INSTANCE(fas_fas) *cohort; + + if (aff_iterate_core(&a, &core)) { + perror("ERROR: Could not affine thread"); + exit(EXIT_FAILURE); + } + + cohort = cohorts + (core / (int)(a.delta)) % n_cohorts; + + while (i--) { + CK_COHORT_RW_WRITE_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL); + { + l = ck_pr_load_uint(&locked); + if (l != 0) { + ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l); + } + + 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); + + l = ck_pr_load_uint(&locked); + if (l != 8) { + ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l); + } + + 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); + + l = ck_pr_load_uint(&locked); + if (l != 0) { + ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l); + } + } + CK_COHORT_RW_WRITE_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL); + + CK_COHORT_RW_READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL); + { + l = ck_pr_load_uint(&locked); + if (l != 0) { + ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l); + } + } + CK_COHORT_RW_READ_UNLOCK(fas_fas, &rw_cohort); + } + + return (NULL); +} + +int +main(int argc, char *argv[]) +{ + pthread_t *threads; + int threads_per_cohort; + ck_spinlock_fas_t *local_lock; + int i; + + if (argc != 4) { + ck_error("Usage: validate \n"); + } + + n_cohorts = atoi(argv[1]); + if (n_cohorts <= 0) { + ck_error("ERROR: Number of cohorts must be greater than 0\n"); + } + + threads_per_cohort = atoi(argv[2]); + if (threads_per_cohort <= 0) { + ck_error("ERROR: Threads per cohort must be greater than 0\n"); + } + + nthr = n_cohorts * threads_per_cohort; + + threads = malloc(sizeof(pthread_t) * nthr); + if (threads == NULL) { + ck_error("ERROR: Could not allocate thread structures\n"); + } + + a.delta = atoi(argv[3]); + + fprintf(stderr, "Creating cohorts..."); + cohorts = malloc(sizeof(CK_COHORT_INSTANCE(fas_fas)) * n_cohorts); + if (cohorts == NULL) { + ck_error("ERROR: Could not allocate base cohort structures\n"); + } + for (i = 0 ; i < n_cohorts ; i++) { + local_lock = malloc(sizeof(ck_spinlock_fas_t)); + CK_COHORT_INIT(fas_fas, cohorts + i, &global_fas_lock, local_lock, + CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT); + } + fprintf(stderr, "done\n"); + + fprintf(stderr, "Creating threads..."); + for (i = 0; i < nthr; i++) { + if (pthread_create(&threads[i], NULL, thread, NULL)) { + ck_error("ERROR: Could not create thread %d\n", i); + } + } + fprintf(stderr, "done\n"); + + fprintf(stderr, "Waiting for threads to finish correctness regression..."); + for (i = 0; i < nthr; i++) + pthread_join(threads[i], NULL); + fprintf(stderr, "done (passed)\n"); + + return (0); +} +