ck_cohort: Added trylock support to cohort framework

ck_pring
Brendon Scheinman 12 years ago
parent 78fbe93caa
commit 3c8728b214

@ -50,6 +50,7 @@ enum ck_cohort_state {
#define CK_COHORT_INIT(N, C, GL, LL, P) ck_cohort_##N##_init(C, GL, LL, P) #define CK_COHORT_INIT(N, C, GL, LL, P) ck_cohort_##N##_init(C, GL, LL, P)
#define CK_COHORT_LOCK(N, C, GC, LC) ck_cohort_##N##_lock(C, GC, LC) #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_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_PROTOTYPE(N, GL, GU, LL, LU) \ #define CK_COHORT_PROTOTYPE(N, GL, GU, LL, LU) \
CK_COHORT_INSTANCE(N) { \ CK_COHORT_INSTANCE(N) { \
@ -112,6 +113,33 @@ enum ck_cohort_state {
return; \ return; \
} }
#define CK_COHORT_TRYLOCK_PROTOTYPE(N, GL, GU, GTL, LL, LU, LTL) \
CK_COHORT_PROTOTYPE(N, GL, GU, LL, LU) \
CK_CC_INLINE static bool \
ck_cohort_##N##_trylock(CK_COHORT_INSTANCE(N) *cohort, \
void *global_context, void *local_context, \
void *local_unlock_context) \
{ \
\
bool trylock_result; \
\
ck_pr_inc_uint(&cohort->waiting_threads); \
trylock_result = LTL(cohort->local_lock, local_context); \
ck_pr_dec_uint(&cohort->waiting_threads); \
if (trylock_result == false) { \
return false; \
} \
\
if (cohort->release_state == CK_COHORT_STATE_GLOBAL && \
GTL(cohort->global_lock, global_context) == false) { \
LU(cohort->local_lock, local_unlock_context); \
return false; \
} \
\
++cohort->acquire_count; \
return true; \
}
#define CK_COHORT_INITIALIZER { \ #define CK_COHORT_INITIALIZER { \
.global_lock = NULL, \ .global_lock = NULL, \
.local_lock = NULL, \ .local_lock = NULL, \

@ -59,9 +59,16 @@ ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)
ck_spinlock_fas_unlock(lock); ck_spinlock_fas_unlock(lock);
} }
CK_COHORT_PROTOTYPE(fas_fas, static bool
ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_trylock_with_context(ck_spinlock_fas_t *lock, void *context)
ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context) {
(void)context;
return ck_spinlock_fas_trylock(lock);
}
CK_COHORT_TRYLOCK_PROTOTYPE(fas_fas,
ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_trylock_with_context,
ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_trylock_with_context)
static CK_COHORT_INSTANCE(fas_fas) *cohorts; static CK_COHORT_INSTANCE(fas_fas) *cohorts;
static int n_cohorts; static int n_cohorts;
@ -81,7 +88,15 @@ thread(void *null CK_CC_UNUSED)
cohort = cohorts + (core / (int)(a.delta)) % n_cohorts; cohort = cohorts + (core / (int)(a.delta)) % n_cohorts;
while (i--) { while (i--) {
if (i & 1) {
CK_COHORT_LOCK(fas_fas, cohort, NULL, NULL); CK_COHORT_LOCK(fas_fas, cohort, NULL, NULL);
} else {
while (CK_COHORT_TRYLOCK(fas_fas, cohort, NULL, NULL, NULL) == false) {
ck_pr_stall();
}
}
{ {
l = ck_pr_load_uint(&locked); l = ck_pr_load_uint(&locked);
if (l != 0) { if (l != 0) {

Loading…
Cancel
Save