ms_sync.c
2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**************************************************************************
* *
* 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)
;
}