ms_sync.c 2.55 KB
/**************************************************************************
 *									  *
 *		 Copyright (C) 1993, Silicon Graphics, Inc.		  *
 *									  *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright law.  They  may  not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *									  *
 **************************************************************************/

/*
 *  ms_sync.c $Revision: 1.2 $
 *
 *  master/slave syncronization routines
 */

#include "ms_sync.h"


/*
 *  Possible values for ms->slave[]
 */
#define MS_GARBAGE	-1
#define MS_SYNC_INIT	10
#define MS_CONTINUE	11
#define MS_DONE		12

/*
 *  Possible values for ms->active[]
 */
#define MS_INACTIVE	0
#define MS_ACTIVE	1

volatile ms_sync_t *ms;


void ms_init_master(long num_slaves)
{
    int i, j;

    /*
     *  Initialize ms structure.
     */
    ms->num_slaves = num_slaves;
    for (i = 0; i < num_slaves; i++)
    {
	ms->active[i] = MS_ACTIVE;
	ms->slave[i] = MS_GARBAGE;
    }

    /*
     *  Syncronize with slaves
     */
    for (j = 0; j < 3; j++)
    {
        for (i = 0; i < ms->num_slaves;)
        {
	    if (ms->slave[i] == MS_DONE)
	        i++;
	    else
#ifdef __sgi__
	        sginap(0);
#else
	        usleep(0);
#endif
        }

        for (i = 0; i < ms->num_slaves; i++)
        {
	    ms->slave[i] = (j < 2) ? MS_SYNC_INIT : MS_CONTINUE;
        }
    }
}


void ms_init_slave(long id)
{
    /*
     *  signal master that this slave is done
     */
    ms->slave[id] = MS_DONE;

    /*
     *  Wait for the master to tell us to continue.
     */
    while (ms->slave[id] != MS_CONTINUE)
    {
	if (ms->slave[id] == MS_SYNC_INIT || ms->slave[id] == MS_GARBAGE)
	    ms->slave[id] = MS_DONE;
#ifdef __sgi__
	sginap(0);
#else
	usleep(0);
#endif
    }
}


void ms_master_sync()
{
    int i;

    /*
     *  Wait for all active slaves to check in.
     */
    for (i = 0; i < ms->num_slaves;)
    {
	if (ms->slave[i] == MS_DONE || ms->active[i] == MS_INACTIVE)
	    i++;
    }

    /*
     *  Signal all slaves to continue.
     */
    for (i = 0; i < ms->num_slaves; i++)
    {
	ms->slave[i] = MS_CONTINUE;
    }
}


void ms_slave_sync(long id)
{
    /*
     *  signal master that this slave is done
     */
    ms->slave[id] = MS_DONE;

    /*
     *  Wait for the master to tell us to continue.
     */
    while (ms->slave[id] != MS_CONTINUE)
	;
}