-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsemaphore.c
More file actions
191 lines (174 loc) · 5.35 KB
/
semaphore.c
File metadata and controls
191 lines (174 loc) · 5.35 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include "semaphore.h"
/***************************************************************
Nombre:
initialize_Semaphore.
Descripcion:
Inicializa los semaforos indicados.
Entrada:
int semid: Identificador del semaforo.
unsigned short *array: Valores iniciales.
Salida:
int: OK si todo fue correcto,
ERROR en caso de error.
************************************************************/
int initialize_Semaphore(int semid, unsigned short *array){
/* Para realizar operaciones de up y down sobre semaforos */
union semun {
int val;
struct semid_ds *semstat;
unsigned short *array;
} vals;
int tamano = sizeof(array) / sizeof(array[0]);
vals.array = array;
if (semctl(semid, tamano, SETALL, vals) == -1) {
return ERROR;
}
return OK;
}
/***************************************************************
Nombre:
erase_Semaphore.
Descripcion:
Borra un semaforo.
Entrada:
int semid: Identificador del semaforo.
Salida:
int: OK si todo fue correcto,
ERROR en caso de error.
***************************************************************/
int erase_Semaphore(int semid) {
if (semctl(semid, 0, IPC_RMID) == -1) {
return ERROR;
}
return OK;
}
/***************************************************************
Nombre:
create_Semaphore.
Descripcion:
Crea un semaforo con la clave y el tamano especificado. Lo inicializa a 0.
Entrada:
key_t key: Clave precompartida del semaforo.
int size: Tamano del semaforo.
Salida:
int *semid: Identificador del semaforo.
int: ERROR en caso de error,
0 si ha creado el semaforo,
1 si ya estaba creado.
**************************************************************/
int create_Semaphore(key_t key, int size, int *semid){
if ((*semid = semget(key, 0, 0)) == -1) {
/* El semaforo no existe asi que debemos crearlo */
*semid = semget(key, size, IPC_CREAT | 0600);
if ((*semid == -1) && (errno == EEXIST)) {
*semid = semget(key, size, SHM_R | SHM_W);
}
if ((semget(key, 0, 0) == -1) || (*semid == -1)) {
return ERROR;
}
} else {
/* El semaforo ya existia */
return 1;
}
return OK;
}
/**************************************************************
Nombre:
down_Semaphore
Descripcion:
Baja el semaforo indicado
Entrada:
int semid: Identificador del semaforo.
int num_sem: Semaforo dentro del array.
int undo: Flag de modo persistente pese a finalizacion abrupta.
Salida:
int: OK si todo fue correcto,
ERROR en caso de error.
***************************************************************/
int down_Semaphore(int id, int num_sem, int undo) {
struct sembuf sem_oper;
sem_oper.sem_num = num_sem;
sem_oper.sem_op = -1; /* Para decrementar en 1 */
sem_oper.sem_flg = undo;
if (semop(id, &sem_oper, 1) == -1){
return ERROR;
}
return OK;
}
/***************************************************************
Nombre:
downMultiple_Semaphore
Descripcion:
Baja todos los semaforos del array indicado por active.
Entrada:
int semid: Identificador del semaforo.
int size: Numero de semaforos del array.
int undo: Flag de modo persistente pese a finalización abrupta.
int *active: Semaforos involucrados.
Salida:
int: OK si todo fue correcto,
ERROR en caso de error.
***************************************************************/
int downMultiple_Semaphore(int id, int size, int undo, int *active) {
int i, j;
for (i = 0; i < size; i++){
for(j = 0; j < size; j++){
if (i == active[j]) {
if (down_Semaphore(id, i, undo) == -1) {
return ERROR;
}
}
}
}
return OK;
}
/**************************************************************
Nombre:
Up_Semaphore
Descripcion:
Sube el semaforo indicado
Entrada:
int semid: Identificador del semaforo.
int num_sem: Semaforo dentro del array.
int undo: Flag de modo persistente pese a finalizacion abupta.
Salida:
int: OK si todo fue correcto,
ERROR en caso de error.
***************************************************************/
int up_Semaphore(int id, int num_sem, int undo) {
struct sembuf sem_oper;
sem_oper.sem_num = num_sem;
sem_oper.sem_op = 1; /* Para aumentar en 1 */
sem_oper.sem_flg = /*(short)*/ undo;
if (semop(id, &sem_oper, 1) == -1){
return ERROR;
}
return OK;
}
/***************************************************************
Nombre:
UpMultiple_Semaphore
Descripcion:
Sube todos los semaforos del array indicado por active.
Entrada:
int semid: Identificador del semaforo.
int size: Numero de semaforos del array.
int undo: Flag de modo persistente pese a finalizacion abrupta.
int *active: Semaforos involucrados.
Salida:
int: OK si todo fue correcto,
ERROR en caso de error.
***************************************************************/
int upMultiple_Semaphore(int id, int size, int undo, int *active) {
int i, j;
for (i = 0; i < size; i++){
for(j = 0; j < size; j++){
if (i == active[j]) {
if (up_Semaphore(id, i, undo) == -1) {
return ERROR;
}
}
}
}
return OK;
}