interface: Made ck_cohort interface more flexible for custom types

ck_pring
Brendon Scheinman 12 years ago
parent 27d841d300
commit 803073b024

@ -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; \
}

@ -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");

@ -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)

@ -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");

Loading…
Cancel
Save