Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
ck_cohort(3)		 BSD Library Functions Manual		  ck_cohort(3)

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 informa-
     tion that the lock	might need for its lock, unlock	and trylock methods.
     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.

NAME | LIBRARY | SYNOPSIS | DESCRIPTION | EXAMPLE | SEE ALSO

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=ck_cohort&sektion=3&manpath=FreeBSD+12.0-RELEASE+and+Ports>

home | help