From 803073b024dbdea680d6974b5a747b2f255b9ede Mon Sep 17 00:00:00 2001 From: Brendon Scheinman Date: Sun, 24 Feb 2013 13:41:35 -0600 Subject: [PATCH] interface: Made ck_cohort interface more flexible for custom types --- include/ck_cohort.h | 31 +++++++++++------- regressions/ck_cohort/benchmark/throughput.c | 34 +++++++++++++------- regressions/ck_cohort/ck_cohort.h | 30 ++++++++++++----- regressions/ck_cohort/validate/validate.c | 32 +++++++++++++----- 4 files changed, 88 insertions(+), 39 deletions(-) diff --git a/include/ck_cohort.h b/include/ck_cohort.h index d74d709..fd647d7 100644 --- a/include/ck_cohort.h +++ b/include/ck_cohort.h @@ -37,12 +37,17 @@ #define CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT 10 -#define CK_COHORT_INSTANCE(N) ck_cohort_##N +#define CK_COHORT_NAME(N) ck_cohort_##N +#define CK_COHORT_INSTANCE(N) struct CK_COHORT_NAME(N) +#define CK_COHORT_INIT(N, C, GL, LL) ck_cohort_##N##_init(C, GL, LL) +#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_PROTOTYPE(N, TG, TL) \ - struct CK_COHORT_INSTANCE(N) { \ - TG *global_lock; \ - TL *local_lock; \ +#define CK_COHORT_PROTOTYPE(N, GT, GL, GU, LT, LL, LU) \ + \ + struct CK_COHORT_NAME(N) { \ + GT *global_lock; \ + LT *local_lock; \ unsigned int release_state; \ unsigned int waiting_threads; \ unsigned int acquire_count; \ @@ -51,7 +56,7 @@ \ CK_CC_INLINE static void \ ck_cohort_##N##_init(struct ck_cohort_##N *cohort, \ - TG *global_lock, TL *local_lock) \ + GT *global_lock, LT *local_lock) \ { \ ck_pr_store_ptr(&cohort->global_lock, global_lock); \ ck_pr_store_ptr(&cohort->local_lock, local_lock); \ @@ -65,14 +70,15 @@ } \ \ CK_CC_INLINE static void \ - ck_cohort_##N##_lock(struct ck_cohort_##N *cohort) \ + ck_cohort_##N##_lock(CK_COHORT_INSTANCE(N) *cohort, \ + void *global_context, void *local_context) \ { \ ck_pr_inc_uint(&cohort->waiting_threads); \ - TL##_lock(cohort->local_lock); \ + LL(cohort->local_lock, local_context); \ ck_pr_dec_uint(&cohort->waiting_threads); \ \ if (cohort->release_state == CK_COHORT_RELEASE_STATE_GLOBAL) { \ - TG##_lock(cohort->global_lock); \ + GL(cohort->global_lock, global_context); \ cohort->release_state = CK_COHORT_RELEASE_STATE_LOCAL; \ } \ \ @@ -82,19 +88,20 @@ } \ \ CK_CC_INLINE static void \ - ck_cohort_##N##_unlock(struct ck_cohort_##N *cohort) \ + ck_cohort_##N##_unlock(CK_COHORT_INSTANCE(N) *cohort, \ + void *global_context, void *local_context) \ { \ if (ck_pr_load_uint(&cohort->waiting_threads) > 0 \ && cohort->acquire_count < cohort->local_pass_limit) { \ cohort->release_state = CK_COHORT_RELEASE_STATE_LOCAL; \ } else { \ - TG##_unlock(cohort->global_lock); \ + GU(cohort->global_lock, global_context); \ cohort->release_state = CK_COHORT_RELEASE_STATE_GLOBAL; \ cohort->acquire_count = 0; \ } \ \ ck_pr_fence_memory(); \ - TL##_unlock(cohort->local_lock); \ + LU(cohort->local_lock, local_context); \ \ return; \ } diff --git a/regressions/ck_cohort/benchmark/throughput.c b/regressions/ck_cohort/benchmark/throughput.c index 4445ec3..a1fb319 100644 --- a/regressions/ck_cohort/benchmark/throughput.c +++ b/regressions/ck_cohort/benchmark/throughput.c @@ -57,11 +57,24 @@ static unsigned int barrier; int critical __attribute__((aligned(64))); -typedef ck_spinlock_fas_t ck_spinlock_fas; -typedef ck_spinlock_ticket_t ck_spinlock_ticket; -CK_COHORT_PROTOTYPE(fas_fas, ck_spinlock_ticket, ck_spinlock_ticket) -static struct ck_cohort_fas_fas *cohorts; -static ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER; +static void +ck_spinlock_ticket_lock_with_context(ck_spinlock_ticket_t *lock, void *context) +{ + (void)context; + ck_spinlock_ticket_lock(lock); +} + +static void +ck_spinlock_ticket_unlock_with_context(ck_spinlock_ticket_t *lock, void *context) +{ + (void)context; + ck_spinlock_ticket_unlock(lock); +} + +CK_COHORT_PROTOTYPE(ticket_ticket, + ck_spinlock_ticket_t, ck_spinlock_ticket_lock_with_context, ck_spinlock_ticket_unlock_with_context, + ck_spinlock_ticket_t, ck_spinlock_ticket_lock_with_context, ck_spinlock_ticket_unlock_with_context) +static CK_COHORT_INSTANCE(ticket_ticket) *cohorts; static ck_spinlock_ticket_t global_ticket_lock = CK_SPINLOCK_TICKET_INITIALIZER; struct block { @@ -76,7 +89,7 @@ fairness(void *null) volatile int j; long int base; unsigned int core; - struct ck_cohort_fas_fas *cohort; + CK_COHORT_INSTANCE(ticket_ticket) *cohort; if (aff_iterate_core(&a, &core)) { perror("ERROR: Could not affine thread"); @@ -91,16 +104,15 @@ fairness(void *null) while (ck_pr_load_uint(&barrier) != nthr); while (ready) { - ck_cohort_fas_fas_lock(cohort); + CK_COHORT_LOCK(ticket_ticket, cohort, NULL, NULL); - fprintf(stderr, "lock acquired by thread %i\n", i); count[i].value++; if (critical) { base = common_lrand48() % critical; for (j = 0; j < base; j++); } - ck_cohort_fas_fas_unlock(cohort); + CK_COHORT_UNLOCK(ticket_ticket, cohort, NULL, NULL); } return (NULL); @@ -145,7 +157,7 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } - cohorts = malloc(sizeof(struct ck_cohort_fas_fas) * n_cohorts); + cohorts = malloc(sizeof(CK_COHORT_INSTANCE(ticket_ticket)) * n_cohorts); if (cohorts == NULL) { ck_error("ERROR: Could not allocate cohort structures\n"); exit(EXIT_FAILURE); @@ -175,7 +187,7 @@ main(int argc, char *argv[]) fprintf(stderr, "Creating cohorts..."); for (i = 0 ; i < n_cohorts ; i++) { - ck_cohort_fas_fas_init(cohorts + i, &global_ticket_lock, local_fas_locks + i); + CK_COHORT_INIT(ticket_ticket, cohorts + i, &global_ticket_lock, local_fas_locks + i); } fprintf(stderr, "done\n"); diff --git a/regressions/ck_cohort/ck_cohort.h b/regressions/ck_cohort/ck_cohort.h index 470e640..1112812 100644 --- a/regressions/ck_cohort/ck_cohort.h +++ b/regressions/ck_cohort/ck_cohort.h @@ -1,10 +1,24 @@ #define LOCK_NAME "ck_cohort" #define LOCK_DEFINE\ - typedef ck_spinlock_fas_t ck_spinlock_fas;\ - static ck_spinlock_fas global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\ - static ck_spinlock_fas local_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\ - CK_COHORT_PROTOTYPE(fas_fas, ck_spinlock_fas, ck_spinlock_fas)\ - static struct ck_cohort_fas_fas CK_CC_CACHELINE cohort = CK_COHORT_INITIALIZER -#define LOCK_INIT ck_cohort_fas_fas_init(&cohort, &global_fas_lock, &local_fas_lock) -#define LOCK ck_cohort_fas_fas_lock(&cohort) -#define UNLOCK ck_cohort_fas_fas_unlock(&cohort) + 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_t, ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context,\ + ck_spinlock_fas_t, 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) +#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/validate/validate.c b/regressions/ck_cohort/validate/validate.c index d43aeda..579154f 100644 --- a/regressions/ck_cohort/validate/validate.c +++ b/regressions/ck_cohort/validate/validate.c @@ -44,9 +44,25 @@ static struct affinity a; static unsigned int locked; static int nthr; static ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER; -typedef ck_spinlock_fas_t ck_spinlock_fas; -CK_COHORT_PROTOTYPE(fas_fas, ck_spinlock_fas, ck_spinlock_fas) -static struct ck_cohort_fas_fas *cohorts; + +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_t, ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, + ck_spinlock_fas_t, ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context) +static CK_COHORT_INSTANCE(fas_fas) *cohorts; static int n_cohorts; static void * @@ -55,7 +71,7 @@ thread(void *null CK_CC_UNUSED) int i = ITERATE; unsigned int l; unsigned int core; - struct ck_cohort_fas_fas *cohort; + CK_COHORT_INSTANCE(fas_fas) *cohort; if (aff_iterate_core(&a, &core)) { perror("ERROR: Could not affine thread"); @@ -65,7 +81,7 @@ thread(void *null CK_CC_UNUSED) cohort = cohorts + (core / (int)(a.delta)) % n_cohorts; while (i--) { - ck_cohort_fas_fas_lock(cohort); + CK_COHORT_LOCK(fas_fas, cohort, NULL, NULL); { l = ck_pr_load_uint(&locked); if (l != 0) { @@ -100,7 +116,7 @@ thread(void *null CK_CC_UNUSED) ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l); } } - ck_cohort_fas_fas_unlock(cohort); + CK_COHORT_UNLOCK(fas_fas, cohort, NULL, NULL); } return (NULL); @@ -138,10 +154,10 @@ main(int argc, char *argv[]) a.delta = atoi(argv[3]); fprintf(stderr, "Creating cohorts..."); - cohorts = malloc(sizeof(struct ck_cohort_fas_fas) * n_cohorts); + cohorts = malloc(sizeof(CK_COHORT_INSTANCE(fas_fas)) * n_cohorts); for (i = 0 ; i < n_cohorts ; i++) { local_lock = malloc(sizeof(ck_spinlock_fas_t)); - ck_cohort_fas_fas_init(cohorts + i, &global_fas_lock, local_lock); + CK_COHORT_INIT(fas_fas, cohorts + i, &global_fas_lock, local_lock); } fprintf(stderr, "done\n");