-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSemSet.c
103 lines (93 loc) · 2.28 KB
/
SemSet.c
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
/* SemSet.c */
#include "SemSet.h"
#include <sys/sem.h>
#define SETS_NEEDED(size) \
(((size) + SYSV_SETS_PER_SEMSET - 1) / (SYSV_SETS_PER_SEMSET))
#define SET_NO(x) ((x) / SYSV_SETS_PER_SEMSET)
#define SEM_NO(x) ((x) % SYSV_SETS_PER_SEMSET)
int
SemSet_Init(SemSet *semset, int size)
{
int sets = SETS_NEEDED(size);
int i;
if (sets > SYSV_SETS_PER_SEMSET) {
PyErr_SetString(PyExc_RuntimeError,
"semaphore set creation failed");
return -1;
}
for (i = 0; i < sets; i++) {
int id = semget(IPC_PRIVATE, MAX_SYSV_SET_SIZE, IPC_CREAT
| S_IREAD | S_IWRITE); //SEM_R | SEM_A);
if (id == -1) {
/* Destroy the sets that have been created so far */
int j;
for (j = 0; j < i; j++)
semctl(semset->setid[j], 0, IPC_RMID);
semset->size = 0;
PyErr_SetString(PyExc_RuntimeError,
"semaphore set creation failed");
return -1;
}
semset->setid[i] = id;
}
semset->size = size;
return 0;
}
void
SemSet_Destroy(SemSet *semset)
{
int sets = SETS_NEEDED(semset->size);
int i;
for (i = 0; i < sets; i++)
semctl(semset->setid[i], 0, IPC_RMID);
}
int
SemSet_Up(SemSet *semset, int n)
{
static struct sembuf op;
int setno, status;
if (n < 0 || n >= semset->size) {
PyErr_SetString(PyExc_RuntimeError,
"semaphore set index out of range");
return -1;
}
setno = SET_NO(n);
do {
LOGF("%d [%d] SemSet_Up", my_pindex, my_pid);
op.sem_num = SEM_NO(n);
op.sem_op = 1;
op.sem_flg = 0;
status = semop(semset->setid[setno], &op, 1);
} while(status == -1 && errno == EINTR);
if (status == -1) {
PyErr_SetFromErrno(PyExc_RuntimeError);
//"semaphore set UP operation failed");
return -1;
}
return 0;
}
int
SemSet_Down(SemSet *semset, int n)
{
static struct sembuf op;
int setno, status;
if (n < 0 || n >= semset->size) {
PyErr_SetString(PyExc_RuntimeError,
"semaphore set index out of range");
return -1;
}
setno = SET_NO(n);
do {
LOGF("%d [%d] SemSet_Down", my_pindex, my_pid);
op.sem_num = SEM_NO(n);
op.sem_op = -1;
op.sem_flg = 0;
status = semop(semset->setid[setno], &op, 1);
} while(status == -1 && errno == EINTR);
if (status == -1) {
PyErr_SetFromErrno(PyExc_RuntimeError);
//"semaphore set DOWN operation failed");
return -1;
}
return 0;
}