1313#include <stdio.h>
1414#include <errno.h>
1515#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 */
1622
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
2023int semctl (int semId ,int semNum ,int flag ,union semun semun )
2124{
22-
23- // Recherche de l'adresse de base de l'area
2425int32 * Address ;
2526area_info info ;
26- //printf("semctl : semid %d, semnum %d, cmd %d\n",semId,semNum,flag);
27+
28+ /* Try to find the pool */
2729if (get_area_info (semId ,& info )!= B_OK )
2830{
29- //printf(" areanot found\n");
31+ /* pool is invalid (BeOS areaid is invalid) */
3032errno = EINVAL ;
3133return -1 ;
3234}
35+
36+ /* Get the pool address */
3337Address = (int32 * )info .address ;
3438
35- // semnum peut etre égal à 0
36- // semun.array contient la valeur de départ du sémaphore
3739
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 */
3944if (flag == SETALL )
4045{
4146long i ;
42- //printf("setall %d\n",Address[0]);
4347for (i = 0 ;i < Address [0 ];i ++ )
4448{
4549int32 cnt ;
50+ /* Get the current count */
4651get_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) */
4854cnt -= semun .array [i ];
4955if (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 );
5157if (cnt < 0 )
5258release_sem_etc (Address [i + 1 ],- cnt ,0 );
5359}
5460return 1 ;
5561}
5662
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 */
5864if (flag == SETVAL )
5965{
6066int32 cnt ;
67+ /* Get the current count */
6168get_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) */
6371cnt -= semun .val ;
6472if (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 );
6674if (cnt < 0 )
6775release_sem_etc (Address [semNum + 1 ],- cnt ,0 );
6876return 1 ;
6977}
7078
71- /*si flag=rm_id il faut supprimer le sémaphore */
79+ /*Delete the pool */
7280if (flag == IPC_RMID )
7381{
7482long i ;
75- // Suppression des sémaphores (ils appartienent au kernel maintenant)
83+
7684thread_info ti ;
77- //printf("remove set\n");
7885get_thread_info (find_thread (NULL ),& ti );
86+
87+ /* Loop over all semaphore to delete them */
7988for (i = 0 ;i < Address [0 ];i ++ )
8089{
90+ /* Don't remember why I do that */
8191set_sem_owner (Address [i + 1 ],ti .team );
92+
93+ /* Delete the semaphore */
8294delete_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 ;
8398}
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 */
85105delete_area (semId );
106+
86107return 1 ;
87108}
88109
89- /*si flag = GETNCNT il faut renvoyer le semaphore count*/
110+ /*Get the current semaphore count */
90111if (flag == GETNCNT )
91112{
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 ;
94116}
95117
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 */
97119if (flag == GETVAL )
98120{
99121int32 cnt ;
100122get_sem_count (Address [semNum + 1 ],& cnt );
101- //printf("semctl getval id : %d cnt : %d\n",semId,cnt);
102123return cnt ;
103124}
104- //printf("semctl erreur\n");
125+
126+ elog (ERROR ,"beos : semctl error : unknown flag" );
127+
105128return 0 ;
106129}
107130
108- // L'area dans laquelle est stockée le poolest identifiée par son nom (convention à moi : SYSV_IPC_SEM : "semId)
131+ /* Find a poolid based on IPC key */
109132int semget (int semKey ,int semNum ,int flags )
110133{
111134char Nom [50 ];
112135area_id parea ;
113136void * Address ;
114137
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 */
117139sprintf (Nom ,"SYSV_IPC_SEM : %d" ,semKey );
118140
119- // Recherche de l' area
141+ /* find area */
120142parea = find_area (Nom );
121143
122- // L' areaexiste
144+ /* Test of areaexistance */
123145if (parea != B_NAME_NOT_FOUND )
124146{
125- //printf("area found\n");
126- // On demande une creatrion d'un pool existant : erreur
147+ /* Area exist and creation is requested, error */
127148if ((flags & IPC_CREAT )&& (flags & IPC_EXCL ))
128149{
129- //printf("creat asking exist\n");
130150errno = EEXIST ;
131151return -1 ;
132152}
133153
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*/
135156parea = clone_area (Nom ,& Address ,B_ANY_ADDRESS ,B_READ_AREA |B_WRITE_AREA ,parea );
136157return parea ;
137158}
138- // L'area n'existe pas
139159else
140160{
141- //printf("set don't exist\n");
142- // Demande de creation
161+ /* Area does not exist, but creation is requested, so create it */
143162if (flags & IPC_CREAT )
144163{
145164int32 * Address ;
146- thread_info ti ;
147165void * Ad ;
148166long i ;
149167
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 */
152169if (semNum > 500 )
153170{
154171errno = ENOSPC ;
155172return -1 ;
156173}
157-
158- // Creation de la zone de mémoire partagée
174+
175+ /* Create the shared memory area which will hold the pool */
159176parea = create_area (Nom ,& Ad ,B_ANY_ADDRESS ,4096 ,B_NO_LOCK ,B_READ_AREA |B_WRITE_AREA );
160177if ((parea == B_BAD_VALUE )|| (parea == B_NO_MEMORY )|| (parea == B_ERROR ))
161178{
162179errno = ENOMEM ;
163180return -1 ;
164181}
182+
183+ /* fill up informations (sem number and sem ids) */
165184Address = (int32 * )Ad ;
166185Address [0 ]= semNum ;
167186for (i = 1 ;i <=Address [0 ];i ++ )
168187{
169- // Creation des sémaphores 1 par 1
188+ /* Create the semaphores */
170189Address [i ]= create_sem (0 ,Nom );
171190
172191if ((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)
176195}
177196}
178197
179- //printf("returned %d\n",parea);
180198return parea ;
181199}
182- // Le pool n'existe pas et pas de demande de création
183200else
184201{
185- // printf("set does not exist nocreat requested\n");
202+ /* Area does not existand nocreation is requested */
186203errno = ENOENT ;
187204return -1 ;
188205}
189206}
190207}
191208
192- // Opération sur le pool de sémaphores
209+ /* Acquire or release in the semaphore pool */
193210int semop (int semId ,struct sembuf * sops ,int nsops )
194211{
195- // Recherche de l'adresse du pool
196- int32 * Address ;
212+ int32 * Address ;/*Pool address*/
197213area_info info ;
198214long i ;
199215
200- //printf("semop id : %d n: %d\n", semId,sops->sem_op);
216+ /* Get the pool address ( semId IS an area id) */
201217get_area_info (semId ,& info );
202218Address = (int32 * )info .address ;
219+
220+ /* Check the validity of semId (it should be an area id) */
203221if ((semId == B_BAD_VALUE )|| (semId == B_NO_MEMORY )|| (semId == B_ERROR ))
204222{
205223errno = EINVAL ;
206224return -1 ;
207225}
208226
209- // Execution de l'action
227+ /* Perform acquire or release */
210228for (i = 0 ;i < nsops ;i ++ )
211229{
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 */
214231if (sops [i ].sem_op < 0 )
215232{
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 );
217235}
218236if (sops [i ].sem_op > 0 )
219237{