FreeBSD Manual Pages
NAME ck_cohort -- generalized interface for lock cohorts LIBRARY Concurrency Kit (libck, -lck) SYNOPSIS #include <ck_cohort.h> CK_COHORT_PROTOTYPE(COHORT_NAME cohort_name, LOCK_FXN global_lock_method, LOCK_FXN global_unlock_method, LOCK_FXN local_lock_method, LOCK_FXN local_unlock_method); CK_COHORT_TRYLOCK_PROTOTYPE(COHORT_NAME cohort_name, LOCK_FXN global_lock_method, LOCK_FXN global_unlock_method, BOOL_LOCK_FXN global_locked_method, BOOL_LOCK_FXN global_trylock_method, LOCK_FXN local_lock_method, LOCK_FXN local_unlock_method, BOOL_LOCK_FXN local_locked_method, BOOL_LOCK_FXN local_trylock_method); CK_COHORT_INSTANCE(COHORT_NAME cohort_name); CK_COHORT_INIT(COHORT_NAME cohort_name, ck_cohort *cohort, void *global_lock, void *local_lock, unsigned int pass_limit); CK_COHORT_LOCK(COHORT_NAME cohort_name, ck_cohort *cohort, void *global_context, void *local_context); CK_COHORT_UNLOCK(COHORT_NAME cohort_name, ck_cohort *cohort, void *global_context, void *local_context); Where LOCK_FXN refers to a method with the signature void(void *lock, void *context) BOOL_LOCK_FXN refers to a method with the signature bool(void *lock, void *context) The context argument in each signature is used to pass along any additional infor- mation that the lock might need for its lock, unlock and trylock meth- ods. The values for this argument are provided to each call to CK_COHORT_LOCK(3), CK_COHORT_UNLOCK(3), CK_COHORT_LOCKED(3), and CK_COHORT_TRYLOCK(3) DESCRIPTION ck_cohort.h provides an interface for defining lock cohorts with arbi- trary lock types. Cohorts are a mechanism for coordinating threads on NUMA architectures in order to reduce the frequency with which a lock is passed between threads on different clusters. Before using a cohort, the user must define a cohort type using either the CK_COHORT_PROTOTYPE() or the CK_COHORT_TRYLOCK_PROTOTYPE() macros. These macros allow the user to specify the lock methods that they would like the cohort to use. See the CK_COHORT_PROTOTYPE(3) and CK_COHORT_TRYLOCK_PROTOTYPE(3) man pages for more details. EXAMPLE #include <stdlib.h> #include <pthread.h> #include <ck_pr.h> #include <ck_cohort.h> #include <ck_spinlock.h> /* * Create cohort 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; } static bool ck_spinlock_locked_with_context(ck_spinlock_t *lock, void *context) { (void)context; return ck_spinlock_locked(lock); } /* * 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_locked_with_context, ck_spinlock_lock_with_context, ck_spinlock_unlock_with_context, ck_spinlock_locked_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; } SEE ALSO CK_COHORT_PROTOTYPE(3), CK_COHORT_TRYLOCK_PROTOTYPE(3), CK_COHORT_INSTANCE(3), CK_COHORT_INITIALIZER(3), CK_COHORT_INIT(3), CK_COHORT_LOCK(3), CK_COHORT_UNLOCK(3), CK_COHORT_LOCKED(3), CK_COHORT_TRYLOCK(3), Additional information available at http://concurrencykit.org/ February 24, 2013. ck_cohort(3)
NAME | LIBRARY | SYNOPSIS | DESCRIPTION | EXAMPLE | SEE ALSO
Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=ck_cohort&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>
