6
These routines simplify the interface to semaphores for use in mutual
7
exclusion and queuing. Hopefully I can also make this portable.
9
An external routine Error is assumed which is called upon an error
10
and tidies up by calling SemSetDestroyAll.
12
In most cases errors cause an internal hard failure (by calling Error).
14
1) make an array of n_sem semaphores, returning the id associated
15
with the entire set. All the semaphore values are initialized to value
16
which should be a positve integer (queuing) or 0 (synchronization).
17
The semaphores in the set are indexed from 0 to n_sem-1.
19
long SemSetCreate(long n_sem, long value)
21
2) Decrement and test the value associated with the semaphore specified by
22
(sem_set_id, sem_num). In effect this:
28
wait in queue for the semaphore
32
void SemWait(long sem_set_id, long sem_num)
34
3) Increment the value associated with the semaphore specified by
35
(sem_set_id, sem_num). If value <= 0 (i.e. there are processes
36
in the queue) this releases the next process.
38
void SemPost(long sem_set_id, long sem_num)
40
4) Return the current value associated with the semaphore sepcified by
41
(sem_set_id, sem_num).
43
long SemValue(long sem_set_id, long sem_num)
45
5) Destroy the set of semaphores. Any other processes that are accessing
46
or try to access the semaphore set should get an error.
47
On the SUN (all system V machines?) the semaphore sets should
48
be destroyed explicitly before the final process exits.
49
0 is returned if OK. -1 implies an error.
51
long SemSetDestroy(long sem_set_id)
53
6) Destroy all the semaphore sets that are known about. This is really
54
meant for an error routine to call to try and tidy up. Though all
55
applications could call it before the last process exits.
56
0 is returned if OK. -1 implies an error.
58
long SemSetDestroyAll()
63
/*************************************************************
64
Alliant Concentrix 5.0 and Concentrix FX/2800
65
*************************************************************/
67
/* This is very specific to the Alliant. */
69
#include <sys/rtsem.h>
70
#include <sys/errno.h>
74
/* On the alliant semaphores are handed out one at a time rather than
75
in sets, so have to maintain sets manually */
77
#define MAX_SEM_SETS 20
80
static struct sem_set_list_struct {
81
int id[MAX_N_SEM]; /* alliant semaphore id */
82
int n_sem; /* no. of semaphores in set */
83
} sem_set_list[MAX_SEM_SETS];
85
static int num_sem_set = 0;
89
/* Initialise sem_set_list */
93
for (i=0; i<MAX_SEM_SETS; i++) {
94
sem_set_list[i].n_sem = 0;
95
for (j=0; j<MAX_N_SEM; j++)
96
sem_set_list[i].id[j] = -1;
100
long SemSetCreate(n_sem, value)
106
/* Check for errors and initialise data if first entry */
108
if ( (n_sem <= 0) || (n_sem >= MAX_N_SEM) )
109
Error("SemSetCreate: n_sem has invalid value", (long) n_sem);
111
if (num_sem_set == 0)
113
else if (num_sem_set >= MAX_SEM_SETS)
114
Error("SemSetCreate: Exceeded man no. of semaphore sets",
117
/* Find first empty slot in sem_set_list */
119
for (i=0; i < MAX_SEM_SETS; i++)
120
if (sem_set_list[i].n_sem == 0)
123
if (i == MAX_SEM_SETS)
124
Error("SemSetCreate: internal error puting semid in list", (long) i);
126
/* Actually make the semaphore set */
128
for (j=0; j<n_sem; j++) {
129
if ( (semid = sem_create(value, value, SEMQUE_FIFO, 0)) < 0)
130
Error("SemSetCreate: failed to create semaphore", (long) j);
131
sem_set_list[i].id[j] = semid;
139
void SemWait(sem_set_id, sem_num)
144
if (sem_wait(sem_set_list[sem_set_id].id[sem_num]) < 0) {
146
goto interrupted; /* got zapped by a signal ... try again */
148
Error("SemWait: error from sem_wait", (long) -1);
152
void SemPost(sem_set_id, sem_num)
156
if (sem_post(sem_set_list[sem_set_id].id[sem_num]) < 0)
157
Error("SemPost: error from sem_post", (long) -1);
160
long SemValue(sem_set_id, sem_num)
166
if (sem_info(sem_set_list[sem_set_id].id[sem_num], &info, sizeof info) < 0)
167
Error("SemValue: error from sem_info", (long) -1);
172
long SemSetDestroy(sem_set_id)
177
/* Close each semaphore in the set */
179
for (i=0; i<sem_set_list[sem_set_id].n_sem; i++) {
180
status += sem_destroy(sem_set_list[sem_set_id].id[i]);
181
sem_set_list[sem_set_id].id[i] = -1;
184
sem_set_list[sem_set_id].n_sem = 0;
191
return (long) status;
194
long SemSetDestroyAll()
198
for (i=0; i<MAX_SEM_SETS; i++)
199
if (sem_set_list[i].n_sem)
200
status += SemSetDestroy(i);
205
return (long) status;