/*
 * This source code was obtained from 
 *     http://www.awl.com/cseng/titles/0-201-63392-2/
 * and is the source code for the programming examples of the book
 * entitled "Programming With POSIX(r) Threads" by Dave Butenhof 
 * (butenhof@zko.dec.com) (thanks Dave!) The original header (which 
 * contains no copyright) is included below. To honor what we perceive
 * as the intention of the original author, there is no claim of
 * Copyright asserted in this file. We have added the log/CVS control
 * info and this text, but otherwise, the code is unmodified from
 * it's original form.
 *
 * The routines in this file implement a useful barrier construct
 * built atop POSIX condition variables and mutexes.
 *
 * The contributors disclaim any representation of warranty: use this
 * code at your own risk.
 *
 * The Code Donkeys at R3vis Corporation.
 */
/*
 * $Revision: 1.3 $
 * $Name: OpenRM-1-6-0-2-c $
 * $Log: barrier.h,v $
 * Revision 1.3  2002/08/19 00:23:17  wes
 * Renamed routines and types to avoid name collision with those used
 * inside OpenRM - makes debug possible on Win32.
 *
 * Revision 1.2  2001/03/31 16:55:18  wes
 * Added procmode.h, which defines an RMpipe processing mode used in
 * most demonstration programs. The default processing mode is
 * RM_PIPE_MULTISTAGE_VIEW_PARALLEL.
 *
 * Revision 1.1  2000/12/02 17:22:55  wes
 * Initial entry.
 *
 */
 

/*
 * barrier.h
 *
 * This header file describes the "barrier" synchronization
 * construct. The type barrier_t describes the full state of the
 * barrier including the POSIX 1003.1c synchronization objects
 * necessary.
 *
 * A barrier causes threads to wait until a set of threads has
 * all "reached" the barrier. The number of threads required is
 * set when the barrier is initialized, and cannot be changed
 * except by reinitializing.
 */

#ifndef __barrier_h
#define __barrier_h

#include <pthread.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Structure describing a barrier.
 */
typedef struct barrier_tag {
    pthread_mutex_t     mutex;          /* Control access to barrier */
    pthread_cond_t      cv;             /* wait for barrier */
    int                 valid;          /* set when valid */
    int                 threshold;      /* number of threads required */
    int                 counter;        /* current number of threads */
    int                 cycle;          /* alternate wait cycles (0 or 1) */
    char                junk[32]; /* wes */
} my_barrier_t;

#define BARRIER_VALID   0x0badcafe

/*
 * Support static initialization of barriers
 */
#define BARRIER_INITIALIZER(cnt) \
    {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, \
    BARRIER_VALID, cnt, cnt, 0}

/*
 * Define barrier functions
 */
extern int my_barrier_init (my_barrier_t *barrier, int count);
extern int my_barrier_destroy (my_barrier_t *barrier);
extern int my_barrier_wait (my_barrier_t *barrier);

#ifdef __cplusplus
}
#endif


#endif
