13
13
#include <stdio.h>
14
14
#include <errno.h>
15
15
#include <OS.h>
16
+ #include "utils/elog.h"
17
+
18
+
19
+ /* Control of a semaphore pool. The pool is an area in which we stored all
20
+ the semIds of the pool. The first 4 bytes are the number of semaphore allocated
21
+ in the pool followed by SemIds */
16
22
17
- // Controle d'un pool de sémaphores
18
- // On considere que le semId utilisé correspond bien a une area de notre adress space
19
- // Les informations du pool de sémaphore sont stockés dans cette area
20
23
int semctl (int semId ,int semNum ,int flag ,union semun semun )
21
24
{
22
-
23
- // Recherche de l'adresse de base de l'area
24
25
int32 * Address ;
25
26
area_info info ;
26
- // printf("semctl : semid %d, semnum %d, cmd %d\n",semId,semNum,flag);
27
+
28
+ /* Try to find the pool */
27
29
if (get_area_info (semId ,& info )!= B_OK )
28
30
{
29
- // printf(" area not found\n");
31
+ /* pool is invalid (BeOS area id is invalid) */
30
32
errno = EINVAL ;
31
33
return -1 ;
32
34
}
35
+
36
+ /* Get the pool address */
33
37
Address = (int32 * )info .address ;
34
38
35
- // semnum peut etre égal à 0
36
- // semun.array contient la valeur de départ du sémaphore
37
39
38
- // si flag = set_all il faut définir la valeur du sémaphore sue semun.array
40
+ /* semNum might be 0 */
41
+ /* semun.array contain the sem initial values */
42
+
43
+ /* Fix the count of all sem of the pool to semun.array */
39
44
if (flag == SETALL )
40
45
{
41
46
long i ;
42
- // printf("setall %d\n",Address[0]);
43
47
for (i = 0 ;i < Address [0 ];i ++ )
44
48
{
45
49
int32 cnt ;
50
+ /* Get the current count */
46
51
get_sem_count (Address [i + 1 ],& cnt );
47
- // printf("Set de ALl %d %d = %d\n",Address[i+1],semun.array[i],cnt);
52
+
53
+ /* Compute and set the new count (relative to the old one) */
48
54
cnt -= semun .array [i ];
49
55
if (cnt > 0 )
50
- acquire_sem_etc (Address [i + 1 ],cnt ,0 ,0 );
56
+ while ( acquire_sem_etc (Address [i + 1 ],cnt ,0 ,0 ) == B_INTERRUPTED );
51
57
if (cnt < 0 )
52
58
release_sem_etc (Address [i + 1 ],- cnt ,0 );
53
59
}
54
60
return 1 ;
55
61
}
56
62
57
- /* si flag = SET_VAL il faut définir la valeur du sémaphore sur semun.val*/
63
+ /* Fix the count of one semaphore to semun.val */
58
64
if (flag == SETVAL )
59
65
{
60
66
int32 cnt ;
67
+ /* Get the current count */
61
68
get_sem_count (Address [semNum + 1 ],& cnt );
62
- // printf("semctl set val id : %d val : %d = %d\n",semId,semun.val,cnt);
69
+
70
+ /* Compute and set the new count (relative to the old one) */
63
71
cnt -= semun .val ;
64
72
if (cnt > 0 )
65
- acquire_sem_etc (Address [semNum + 1 ],cnt ,0 ,0 );
73
+ while ( acquire_sem_etc (Address [semNum + 1 ],cnt ,0 ,0 ) == B_INTERRUPTED );
66
74
if (cnt < 0 )
67
75
release_sem_etc (Address [semNum + 1 ],- cnt ,0 );
68
76
return 1 ;
69
77
}
70
78
71
- /* si flag=rm_id il faut supprimer le sémaphore */
79
+ /* Delete the pool */
72
80
if (flag == IPC_RMID )
73
81
{
74
82
long i ;
75
- // Suppression des sémaphores (ils appartienent au kernel maintenant)
83
+
76
84
thread_info ti ;
77
- // printf("remove set\n");
78
85
get_thread_info (find_thread (NULL ),& ti );
86
+
87
+ /* Loop over all semaphore to delete them */
79
88
for (i = 0 ;i < Address [0 ];i ++ )
80
89
{
90
+ /* Don't remember why I do that */
81
91
set_sem_owner (Address [i + 1 ],ti .team );
92
+
93
+ /* Delete the semaphore */
82
94
delete_sem (Address [i + 1 ]);
95
+
96
+ /* Reset to an invalid semId (in case other process try to get the infos from a cloned area */
97
+ Address [i + 1 ]= 0 ;
83
98
}
84
- // Il faudrait supprimer en boucle toutes les area portant le même nom
99
+
100
+ /* Set the semaphore count to 0 */
101
+ Address [0 ]= 0 ;
102
+
103
+ /* Delete the area (it might be cloned by other process. Let them live with it,
104
+ in all cases semIds are 0 so if another process try to use it, it will fail */
85
105
delete_area (semId );
106
+
86
107
return 1 ;
87
108
}
88
109
89
- /* si flag = GETNCNT il faut renvoyer le semaphore count*/
110
+ /* Get the current semaphore count */
90
111
if (flag == GETNCNT )
91
112
{
92
- // printf("getncnt : impossible sur BeOS\n");
93
- return 0 ; // a faire (peut etre impossible sur Beos)
113
+ /* TO BE IMPLEMENTED */
114
+ elog (ERROR ,"beos : semctl error : GETNCNT not implemented" );
115
+ return 0 ;
94
116
}
95
117
96
- /* si flag = GETVAL il faut renvoyer la valeur du sémaphore */
118
+ /* Get the current semaphore count of the first semaphore in the pool */
97
119
if (flag == GETVAL )
98
120
{
99
121
int32 cnt ;
100
122
get_sem_count (Address [semNum + 1 ],& cnt );
101
- // printf("semctl getval id : %d cnt : %d\n",semId,cnt);
102
123
return cnt ;
103
124
}
104
- // printf("semctl erreur\n");
125
+
126
+ elog (ERROR ,"beos : semctl error : unknown flag" );
127
+
105
128
return 0 ;
106
129
}
107
130
108
- // L'area dans laquelle est stockée le pool est identifiée par son nom (convention à moi : SYSV_IPC_SEM : "semId)
131
+ /* Find a pool id based on IPC key */
109
132
int semget (int semKey , int semNum , int flags )
110
133
{
111
134
char Nom [50 ];
112
135
area_id parea ;
113
136
void * Address ;
114
137
115
- // printf("semget get k: %d n: %d fl:%d\n",semKey,semNum,flags);
116
- // Construction du nom que doit avoir l'area
138
+ /* Name of the area to find */
117
139
sprintf (Nom ,"SYSV_IPC_SEM : %d" ,semKey );
118
140
119
- // Recherche de l' area
141
+ /* find area */
120
142
parea = find_area (Nom );
121
143
122
- // L' area existe
144
+ /* Test of area existance */
123
145
if (parea != B_NAME_NOT_FOUND )
124
146
{
125
- // printf("area found\n");
126
- // On demande une creatrion d'un pool existant : erreur
147
+ /* Area exist and creation is requested, error */
127
148
if ((flags & IPC_CREAT )&& (flags & IPC_EXCL ))
128
149
{
129
- // printf("creat asking exist\n");
130
150
errno = EEXIST ;
131
151
return -1 ;
132
152
}
133
153
134
- // Clone de l'area et renvoi de son ID
154
+ /* Get an area clone (in case it's not in our address space) */
155
+ /* TODO : a check of address space might be done to avoid duplicate areas in the same address space*/
135
156
parea = clone_area (Nom ,& Address ,B_ANY_ADDRESS ,B_READ_AREA | B_WRITE_AREA ,parea );
136
157
return parea ;
137
158
}
138
- // L'area n'existe pas
139
159
else
140
160
{
141
- // printf("set don't exist\n");
142
- // Demande de creation
161
+ /* Area does not exist, but creation is requested, so create it */
143
162
if (flags & IPC_CREAT )
144
163
{
145
164
int32 * Address ;
146
- thread_info ti ;
147
165
void * Ad ;
148
166
long i ;
149
167
150
- // printf("create set\n");
151
- // On ne peut pas creer plus de 500 semaphores dans un pool (limite tout à fait arbitraire de ma part)
168
+ /* Limit to 500 semaphore in a pool */
152
169
if (semNum > 500 )
153
170
{
154
171
errno = ENOSPC ;
155
172
return -1 ;
156
173
}
157
-
158
- // Creation de la zone de mémoire partagée
174
+
175
+ /* Create the shared memory area which will hold the pool */
159
176
parea = create_area (Nom ,& Ad ,B_ANY_ADDRESS ,4096 ,B_NO_LOCK ,B_READ_AREA | B_WRITE_AREA );
160
177
if ((parea == B_BAD_VALUE )|| (parea == B_NO_MEMORY )|| (parea == B_ERROR ))
161
178
{
162
179
errno = ENOMEM ;
163
180
return -1 ;
164
181
}
182
+
183
+ /* fill up informations (sem number and sem ids) */
165
184
Address = (int32 * )Ad ;
166
185
Address [0 ]= semNum ;
167
186
for (i = 1 ;i <=Address [0 ];i ++ )
168
187
{
169
- // Creation des sémaphores 1 par 1
188
+ /* Create the semaphores */
170
189
Address [i ]= create_sem (0 ,Nom );
171
190
172
191
if ((Address [i ]== B_BAD_VALUE )|| (Address [i ]== B_NO_MEMORY )|| (Address [i ]== B_NO_MORE_SEMS ))
@@ -176,44 +195,43 @@ int semget(int semKey, int semNum, int flags)
176
195
}
177
196
}
178
197
179
- // printf("returned %d\n",parea);
180
198
return parea ;
181
199
}
182
- // Le pool n'existe pas et pas de demande de création
183
200
else
184
201
{
185
- // printf("set does not exist no creat requested\n");
202
+ /* Area does not exist and no creation is requested */
186
203
errno = ENOENT ;
187
204
return -1 ;
188
205
}
189
206
}
190
207
}
191
208
192
- // Opération sur le pool de sémaphores
209
+ /* Acquire or release in the semaphore pool */
193
210
int semop (int semId , struct sembuf * sops , int nsops )
194
211
{
195
- // Recherche de l'adresse du pool
196
- int32 * Address ;
212
+ int32 * Address ; /*Pool address*/
197
213
area_info info ;
198
214
long i ;
199
215
200
- // printf("semop id : %d n: %d\n", semId,sops->sem_op);
216
+ /* Get the pool address ( semId IS an area id) */
201
217
get_area_info (semId ,& info );
202
218
Address = (int32 * )info .address ;
219
+
220
+ /* Check the validity of semId (it should be an area id) */
203
221
if ((semId == B_BAD_VALUE )|| (semId == B_NO_MEMORY )|| (semId == B_ERROR ))
204
222
{
205
223
errno = EINVAL ;
206
224
return -1 ;
207
225
}
208
226
209
- // Execution de l'action
227
+ /* Perform acquire or release */
210
228
for (i = 0 ;i < nsops ;i ++ )
211
229
{
212
-
213
- // printf("semid %d, n %d\n",Address[sops[i].sem_num+1],sops[i].sem_op);
230
+ /* For each sem in the pool, check the operation to perform */
214
231
if (sops [i ].sem_op < 0 )
215
232
{
216
- acquire_sem_etc (Address [sops [i ].sem_num + 1 ],- sops [i ].sem_op ,0 ,0 );
233
+ /* Try acuiring the semaphore till we are not inteerupted by a signal */
234
+ while (acquire_sem_etc (Address [sops [i ].sem_num + 1 ],- sops [i ].sem_op ,0 ,0 )== B_INTERRUPTED );
217
235
}
218
236
if (sops [i ].sem_op > 0 )
219
237
{
0 commit comments