diff --git a/doc/CK_COHORT_INIT b/doc/CK_COHORT_INIT index b440a80..702764f 100644 --- a/doc/CK_COHORT_INIT +++ b/doc/CK_COHORT_INIT @@ -1,5 +1,4 @@ .\" -.\" Copyright 2013 Samy Al Bahra. .\" Copyright 2013 Brendon Scheinman. .\" All rights reserved. .\" diff --git a/doc/CK_COHORT_INSTANCE b/doc/CK_COHORT_INSTANCE index 9ed728d..1230b26 100644 --- a/doc/CK_COHORT_INSTANCE +++ b/doc/CK_COHORT_INSTANCE @@ -1,5 +1,4 @@ .\" -.\" Copyright 2013 Samy Al Bahra. .\" Copyright 2013 Brendon Scheinman. .\" All rights reserved. .\" diff --git a/doc/CK_COHORT_LOCK b/doc/CK_COHORT_LOCK index 6d3af0c..9ea6342 100644 --- a/doc/CK_COHORT_LOCK +++ b/doc/CK_COHORT_LOCK @@ -1,5 +1,4 @@ .\" -.\" Copyright 2013 Samy Al Bahra. .\" Copyright 2013 Brendon Scheinman. .\" All rights reserved. .\" diff --git a/doc/CK_COHORT_UNLOCK b/doc/CK_COHORT_UNLOCK index 0ee95bc..60d6133 100644 --- a/doc/CK_COHORT_UNLOCK +++ b/doc/CK_COHORT_UNLOCK @@ -1,5 +1,4 @@ .\" -.\" Copyright 2013 Samy Al Bahra. .\" Copyright 2013 Brendon Scheinman. .\" All rights reserved. .\" diff --git a/doc/ck_cohort b/doc/ck_cohort index 037388d..8c5a5a1 100644 --- a/doc/ck_cohort +++ b/doc/ck_cohort @@ -1,5 +1,4 @@ .\" -.\" Copyright 2013 Samy Al Bahra. .\" Copyright 2013 Brendon Scheinman. .\" All rights reserved. .\" @@ -56,6 +55,112 @@ man page for more details. Cohort instances do not allocate any new memory, so they can be freed after use without using an explicit dispose method. .Pp +.Sh EXAMPLE +.Bd -literal -offset indent + +#include +#include + +#include +#include +#include + +/* + * Create lock/unlock methods with signatures that match + * the required signature + */ +static void +ck_spinlock_lock_with_context(ck_spinlock_t *lock, void *context) +{ + (void)context; + ck_spinlock_lock(lock); + return; +} + +static void +ck_spinlock_unlock_with_context(ck_spinlock_t *lock, void *context) +{ + (void)context; + ck_spinlock_unlock(lock); + return; +} + +/* + * define a cohort type named "test_cohort" that will use + * the above methods for both its global and local locks + */ +CK_COHORT_PROTOTYPE(test_cohort, + ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context, + ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context) + +static ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER; +static unsigned int ready; + +static void* +function(void *context) +{ + CK_COHORT_INSTANCE(test_cohort) *cohort = context; + + while (ready == 0); + + while (ready > 0) { + /* + * acquire the cohort lock before performing critical section. + * note that we pass NULL for both the global and local context + * arguments because neither the lock nor unlock functions + * will use them. + */ + CK_COHORT_LOCK(test_cohort, cohort, NULL, NULL); + + /* perform critical section */ + + /* relinquish cohort lock */ + CK_COHORT_UNLOCK(test_cohort, cohort, NULL, NULL); + } + + return NULL; +} + +int +main(void) +{ + unsigned int nthr = 4; + unsigned int n_cohorts = 2; + unsigned int i; + + /* allocate 2 cohorts of the defined type */ + CK_COHORT_INSTANCE(test_cohort) *cohorts = + calloc(n_cohorts, sizeof(CK_COHORT_INSTANCE(test_cohort))); + + /* create local locks to use with each cohort */ + ck_spinlock_t *local_locks = + calloc(n_cohorts, sizeof(ck_spinlock_t)); + + pthread_t *threads = + calloc(nthr, sizeof(pthread_t)); + + /* initialize each of the cohorts before using them */ + for (i = 0 ; i < n_cohorts ; ++i) { + CK_COHORT_INIT(test_cohort, cohorts + i, &global_lock, local_locks + i, + CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT); + } + + /* start each thread and assign cohorts equally */ + for (i = 0 ; i < nthr ; ++i) { + pthread_create(threads + i, NULL, function, cohorts + (i % n_cohorts)); + } + + ck_pr_store_uint(&ready, 1); + sleep(10); + ck_pr_store_uint(&ready, 0); + + for (i = 0 ; i < nthr ; ++i) { + pthread_join(threads[i], NULL); + } + + return 0; +} + .Sh SEE ALSO .Xr CK_COHORT_PROTOTYPE 3 , .Xr CK_COHORT_INSTANCE 3 , diff --git a/include/ck_cohort.h b/include/ck_cohort.h index 7ad8aea..4e1c4ba 100644 --- a/include/ck_cohort.h +++ b/include/ck_cohort.h @@ -51,10 +51,10 @@ 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_PROTOTYPE(N, GT, GL, GU, LT, LL, LU) \ +#define CK_COHORT_PROTOTYPE(N, GL, GU, LL, LU) \ CK_COHORT_INSTANCE(N) { \ - GT *global_lock; \ - LT *local_lock; \ + void *global_lock; \ + void *local_lock; \ enum ck_cohort_state release_state; \ unsigned int waiting_threads; \ unsigned int acquire_count; \ @@ -63,7 +63,7 @@ enum ck_cohort_state { \ CK_CC_INLINE static void \ ck_cohort_##N##_init(struct ck_cohort_##N *cohort, \ - GT *global_lock, LT *local_lock, unsigned int pass_limit) \ + void *global_lock, void *local_lock, unsigned int pass_limit) \ { \ cohort->global_lock = global_lock; \ cohort->local_lock = local_lock; \