/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 */

#ident	"$Header: sbarrier.c 1.2 89/05/31 $"

/*
 * sbarrier.c
 *	Implementation of C and Fortran callable spin-barrier function.
 *
 * Barrier usage:
 *
 *	s_init_barrier(&barrier, nprocs);
 *	...
 *	s_wait_barrier(&barrier);
 *
 * The "wait" does not return until nprocs have all called s_wait_barrier().
 * Results are undefined if more than nprocs try to wait at the barrier.
 *
 * A barrier can be initialized multiple times, as long as no initialization
 * occurs when the barrier is in use.
 */

#include "parallel.h"
#include "parc.h"

/*
 * s_init_barrier()
 *	Initialize a barrier to assume given number of participants.
 *
 * This can be called again any time the barrier is not in use.
 */

s_init_barrier(b, limit)
	sbarrier_t *b;
	int limit;
{
	S_INIT_BARRIER(b, limit);
}

/*
 * fortran version
 */

s_init_barrier_(b, limit)
	sbarrier_t *b;
	int *limit;
{
	S_INIT_BARRIER(b, *limit);
}

/*
 * s_finit_barrier()
 *	Fortran callable version of s_init_barrier().  Same args in
 *	DIFFERENT order, and by reference.
 */

#ifndef lint
static
#endif
s_finit_barrier(limitp, b)
	int	*limitp;
	sbarrier_t *b;
{
	S_INIT_BARRIER(b, *limitp);
}

/*
 * s_f1init_barrier()
 *	V2.9.1 Fortran callable version of s_init_barrier(). Same args in
 *	SAME order, and by reference.
 */

#ifndef lint
static
#endif
s_f1init_barrier(b, limitp)
	sbarrier_t *b;
	int	*limitp;
{
	S_INIT_BARRIER(b, *limitp);
}

/*
 * s_wait_barrier()
 *	Wait at barrier until all participants wait.
 *
 * All callers block at the barrier until 'limit' processes have entered
 * the barrier.  At that point they all leave.
 *
 * Algorithm uses a current "use-count" (b_useno) to sense when barrier
 * can "open".  The important point is that all processes entering the
 * barrier see the same value of b_useno, and this value changes when
 * last process enters the barrier.  It is ok for b_useno to wrap-around.
 *
 * No process will leave the barrier until the use-count has changed
 * state.  It *is* possible for a process(es) to re-enter the barrier
 * before all processes have fully exited previous use; however, this
 * entry uses new value of use-count, thus avoiding races.
 *
 * This code won't work correctly if more than `limit' processes attempt
 * to use the barrier.
 */

s_wait_barrier(b)
	sbarrier_t *b;
{
	S_WAIT_BARRIER(b);
}

/*
 * fortran version
 */
s_wait_barrier_(b)
	sbarrier_t *b;
{
	S_WAIT_BARRIER(b);
}

/* Generate Fortran and Pascal -e entry points */
/* ENTRY(s_init_barrier, s_finit_barrier); */
/* ENTRY(s_wait_barrier, _s_wait_barrier); */

/* Fortran V2.9.1 entry points */
/* ENTRY(s_init_barrier_, s_f1init_barrier); */
/* ENTRY(s_wait_barrier_, s_wait_barrier); */
