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

FreeBSD Manual Pages

  
 
  

home | help
NAME
       ck_rwcohort  -- generalized interface for reader-writer locks using co-
       hort locks

LIBRARY
       Concurrency Kit (libck, -lck)

SYNOPSIS
       #include	<ck_rwcohort.h>
       In each of the following	macros,	"STRATEGY" should be replaced with ei-
       ther "NEUTRAL", "RP", or	"WP" depending on which	locking	 strategy  the
       user prefers.  RP and WP	represent reader preference and	writer prefer-
       ence,  respectively,  while  NEUTRAL  represents	 a strategy neutral to
       reads vs. writes.

       CK_RWCOHORT_STRATEGY_PROTOTYPE(COHORT_NAME cohort_name);

       CK_RWCOHORT_STRATEGY_NAME(COHORT_NAME cohort_name);

       CK_RWCOHORT_STRATEGY_INSTANCE(COHORT_NAME cohort_name);

       CK_RWCOHORT_STRATEGY_INIT(COHORT_NAME   cohort_name,   RWCOHORT	 lock,
	   unsigned int	wait_limit);
       Note:  the  wait_limit  argument	 should	be omitted for locks using the
       neutral strategy

       CK_RWCOHORT_STRATEGY_READ_LOCK(COHORT_NAME cohort_name, RWCOHORT	 lock,
	   COHORT cohort, void *global_context,	void *local_context);

       CK_RWCOHORT_STRATEGY_READ_UNLOCK(COHORT_NAME		  cohort_name,
	   RWCOHORT    lock,	COHORT	  cohort,    void     *global_context,
	   void	*local_context);

       CK_RWCOHORT_STRATEGY_WRITE_LOCK(COHORT_NAME cohort_name,	RWCOHORT lock,
	   COHORT cohort, void *global_context,	void *local_context);

       CK_RWCOHORT_STRATEGY_WRITE_UNLOCK(COHORT_NAME		  cohort_name,
	   RWCOHORT    lock,	COHORT	  cohort,    void     *global_context,
	   void	*local_context);

       Arguments  of  type  RWCOHORT must be pointers to structs defined using
       the CK_RWCOHORT_STRATEGY_PROTOTYPE(3) macro with	the same strategy  and
       cohort name as the current call.

       Arguments  of type COHORT must be pointers to structs defined using the
       CK_COHORT_PROTOTYPE(3) macro.

DESCRIPTION
       ck_rwcohort.h provides an interface for	defining  reader-writer	 locks
       that use	cohort locks internally	to increase performance	on NUMA	archi-
       tectures.  See ck_cohort(3) for more information	about cohort locks.

       Before using a reader-writer cohort lock, the user must define a	cohort
       type	using	  either    the	   CK_COHORT_PROTOTYPE(3)    or	   the
       CK_COHORT_TRYLOCK_PROTOTYPE(3) macros, and define a reader-writer  lock
       type using the CK_RWCOHORT_PROTOTYPE(3) macro.

EXAMPLE
	     #include <stdlib.h>
	     #include <pthread.h>

	     #include <ck_pr.h>
	     #include <ck_cohort.h>
	     #include <ck_rwcohort.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)

	     /*	define a reader-writer type using the same cohort type */
	     CK_RWCOHORT_WP_PROTOTYPE(test_cohort)

	     static ck_spinlock_t global_lock =	CK_SPINLOCK_INITIALIZER;
	     static CK_COHORT_INSTANCE(test_cohort) *cohorts;
	     static CK_RWCOHORT_WP_INSTANCE(test_cohort) rw_cohort = CK_RWCOHORT_WP_INITIALIZER;
	     static unsigned int ready;

	     static void *
	     function(void *context)
	     {
		     CK_COHORT_INSTANCE(test_cohort) *cohort = context;

		     while (ck_pr_load_uint(&ready) == 0);

		     while (ck_pr_load_uint(&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/

				April 23, 2013.			ck_rwcohort(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=ck_rwcohort&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help