1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/openenvcore/include/sys/sem.dosc Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,487 @@
1.4 +/** @file ../include/sys/sem.h
1.5 +@internalComponent
1.6 +*/
1.7 +
1.8 +/** @fn semget(key_t key, int nsems, int semflg)
1.9 +@param key
1.10 +@param nsems
1.11 +@param semflg
1.12 +@return The semget call
1.13 +returns the id of a semaphore set if successful; otherwise, -1
1.14 +is returned and errno is set to indicate the error.
1.15 +
1.16 +@code
1.17 + SEM_R Read access for user.
1.18 + SEM_A Alter access for user.
1.19 + ( SEM_R>>3 )
1.20 + Read access for group.
1.21 + ( SEM_A>>3 )
1.22 + Alter access for group.
1.23 + ( SEM_R>>6 )
1.24 + Read access for other.
1.25 + ( SEM_A>>6 )
1.26 + Alter access for other.
1.27 +
1.28 +Note:The 'group' flags (SEM_R >> 3 and SEM_A >> 3) are ignored in Symbian OS.
1.29 +@endcode
1.30 + Based on the values of key and semflg, semget returns the identifier of a newly created or previously existing
1.31 +set of semaphores. The key
1.32 +is analogous to a filename: it provides a handle that names an
1.33 +IPC object.
1.34 +There are three ways to specify a key: IPC_PRIVATE may be specified, in which case a new IPC object
1.35 +will be created. An integer constant may be specified.
1.36 +If no IPC object corresponding
1.37 +to key is specified and the IPC_CREAT bit is set in semflg, a new one will be created. The ftok function
1.38 +may be used to generate a key from a pathname.
1.39 +
1.40 +@code
1.41 +
1.42 + The mode of a newly created IPC object is determined by OR 'ing the following constants into the semflg argument: SEM_R Read access for user. SEM_A Alter access for user. ( SEM_R>>3 ) Read access for group. ( SEM_A>>3 ) Alter access for group. ( SEM_R>>6 ) Read access for other. ( SEM_A>>6 ) Alter access for other.
1.43 +@endcode
1.44 +
1.45 +
1.46 + If a new set of semaphores is being created, nsems is used to indicate the number of semaphores the set should contain.
1.47 +Otherwise, nsems may be specified as 0.
1.48 +
1.49 +Examples:
1.50 +@code
1.51 +#include <sys/ipc.h>
1.52 +#include <sys/sem.h>
1.53 +#include <stdio.h>
1.54 +#include <errno.h>
1.55 +
1.56 +#define SEM_SET_KEY 1000
1.57 +#define NO_OF_SEMAPHORES 2
1.58 +
1.59 +int main(void)
1.60 +{
1.61 + int sem_set_id;
1.62 + int perm;
1.63 + /*
1.64 + * Create 2 semaphores in a set, with access only to
1.65 + * the owner
1.66 + */
1.67 + perm = SEM_R | SEM_A;
1.68 + if((sem_set_id = semget(SEM_SET_KEY, NO_OF_SEMAPHORES, IPC_CREAT | perm))
1.69 + == -1) {
1.70 + printf("Semaphore creation failed with errno %d", errno);
1.71 + return -1;
1.72 + }
1.73 + return 0;
1.74 +}
1.75 +@endcode
1.76 +
1.77 +@code
1.78 +Note :If the user need to create a semaphore which can be accessed from a different process, the 'other' flags (SEM_R >> 6 and SEM_A >> 6) must be added in parameter of shmflg.
1.79 +e.g The value of the variable perm used in the above example code should be as below
1.80 +perm = SEM_R | SEM_A | SEM_R >> 6 | SEM_A >> 6
1.81 +@endcode
1.82 +
1.83 +@see semctl()
1.84 +@see semop()
1.85 +@see ftok()
1.86 +
1.87 +
1.88 +
1.89 +
1.90 +@publishedAll
1.91 +@externallyDefinedApi
1.92 +*/
1.93 +
1.94 +/** @fn semop(int semid, struct sembuf *sops, unsigned nsops)
1.95 +@param semid
1.96 +@param sops
1.97 +@param nsops
1.98 +@return The semop function returns 0 if successful; otherwise the
1.99 +value -1 is returned and errno is set to indicate the error.
1.100 +
1.101 + The semop system call
1.102 +atomically performs the array of operations indicated by array on the semaphore set indicated by semid. The length of array is indicated by nops. Each operation is encoded in a struct sembuf ,
1.103 +which is defined as follows:
1.104 +
1.105 +@code
1.106 +struct sembuf {
1.107 + u_short sem_num; /* semaphore # */
1.108 + short sem_op; /* semaphore operation */
1.109 + short sem_flg; /* operation flags */
1.110 +};
1.111 +@endcode
1.112 +
1.113 + For each element in array, sem_op and sem_flg determine an operation to be performed on semaphore number sem_num in the set.
1.114 +The values SEM_UNDO and IPC_NOWAIT may be ORed into the sem_flg member in order to modify the behavior of the given operation.
1.115 +
1.116 + The operation performed depends as follows on the value of sem_op: When sem_op is positive and the process has alter permission,
1.117 +the semaphore's value is incremented by sem_op's value.
1.118 +If SEM_UNDO is specified, the semaphore's adjust on exit value is decremented by sem_op's value.
1.119 +A positive value for sem_op generally corresponds to a process releasing a resource
1.120 +associated with the semaphore. The behavior when sem_op is negative and the process has alter permission,
1.121 +depends on the current value of the semaphore: If the current value of the semaphore is greater than or equal to
1.122 +the absolute value of sem_op, then the value is decremented by the absolute value of sem_op. If SEM_UNDO is specified, the semaphore's adjust on exit
1.123 +value is incremented by the absolute value of sem_op. If the current value of the semaphore is less than the absolute value of sem_op, one of the following happens: If IPC_NOWAIT was specified, then semop returns immediately with a return value of EAGAIN. Otherwise, the calling process is put to sleep until one of the following
1.124 +conditions is satisfied: Some other process removes the semaphore with the IPC_RMID option of semctl .
1.125 +In this case, semop returns immediately with a return value of EIDRM. The semaphore's
1.126 +value is greater than or equal to the absolute value of sem_op. When this condition becomes true, the semaphore's value is decremented
1.127 +by the absolute value of sem_op, the semaphore's adjust on exit value is incremented by the
1.128 +absolute value of sem_op.
1.129 +
1.130 + A negative value for sem_op generally means that a process is waiting for a resource to become
1.131 +available. When sem_op is zero and the process has read permission,
1.132 +one of the following will occur: If the current value of the semaphore is equal to zero
1.133 +then semop can return immediately. If IPC_NOWAIT was specified, then semop returns immediately with a return value of EAGAIN. Otherwise, the calling process is put to sleep until one of the following
1.134 +conditions is satisfied: Some other process removes the semaphore with the IPC_RMID option of semctl .
1.135 +In this case, semop returns immediately with a return value of EIDRM. The semaphore's value becomes zero.
1.136 +
1.137 + For each semaphore a process has in use, an "adjust on exit"
1.138 +value is maintained, as alluded to earlier.
1.139 +When a process
1.140 +exits, either voluntarily or involuntarily, the adjust on exit value
1.141 +for each semaphore is added to the semaphore's value.
1.142 +This can
1.143 +be used to insure that a resource is released if a process terminates
1.144 +unexpectedly.
1.145 +
1.146 +Examples:
1.147 +@code
1.148 +#include <sys/ipc.h>
1.149 +#include <sys/sem.h>
1.150 +#include <stdio.h>
1.151 +
1.152 +void File_Update(char* path, int val)
1.153 +{
1.154 + struct sembuf sem_op;
1.155 + FILE* fp;
1.156 + /*
1.157 + * Wait on the semaphore till the value is non-negative.
1.158 + */
1.159 + sem_op.sem_num = 0;
1.160 + sem_op.sem_op = -1;
1.161 + sem_op.sem_flg = 0;
1.162 + semop(sem_set_id, &sem;_op, 1);
1.163 + /*
1.164 + * If we are here, then We have locked the semaphore,
1.165 + * and are assured exclusive access to file.
1.166 + * We can now manipulate the file
1.167 + */
1.168 + fp = fopen(path, "w");
1.169 + if (fp) {
1.170 + fprintf(fp, "%d", val);
1.171 + fclose(fp);
1.172 + }
1.173 + /*
1.174 + * Increase the value of the semaphore by 1 so that others blocked on
1.175 + * this semaphore get awakened.
1.176 + */
1.177 + sem_op.sem_num = 0;
1.178 + sem_op.sem_op = 1;
1.179 + sem_op.sem_flg = 0;
1.180 + semop(sem_set_id, &sem;_op, 1);
1.181 +}
1.182 +
1.183 +@endcode
1.184 +@see semctl()
1.185 +@see semget()
1.186 +
1.187 +
1.188 +Bugs:
1.189 +
1.190 + The semop system call
1.191 +may block waiting for memory even if IPC_NOWAIT was specified.
1.192 +
1.193 +
1.194 +
1.195 +@publishedAll
1.196 +@externallyDefinedApi
1.197 +*/
1.198 +
1.199 +/** @fn semctl(int semid, int semnum, int cmd, ...)
1.200 +@param semid
1.201 +@param semnum
1.202 +@param cmd
1.203 +@param ...
1.204 +@return On success, when cmd is one of GETVAL, GETPID, GETNCNT or GETZCNT, semctl returns the corresponding value; otherwise, 0 is returned.
1.205 +On failure, -1 is returned, and errno is set to indicate the error.
1.206 +
1.207 +@code
1.208 + IPC_STAT Fetch the semaphore sets struct semid_ds ,
1.209 + storing it in the memory pointed to by arg.buf .
1.210 + IPC_SET Changes the sem_perm.uid, sem_perm.gid, and sem_perm.mode members of the semaphore sets struct semid_ds to match those of the struct pointed to by arg.buf.
1.211 + IPC_RMID Immediately removes the semaphore set from the system.
1.212 + The calling
1.213 + processe'ss uid must equal the semaphore sets sem_perm.uid or sem_perm.cuid,
1.214 + GETVAL Return the value of semaphore number semnum.
1.215 + SETVAL Set the value of semaphore number semnum to arg.val. Outstanding adjust on exit values for this semaphore in any process
1.216 + are cleared.
1.217 + GETPID Return the pid of the last process to perform an operation on
1.218 + semaphore number semnum.
1.219 + GETNCNT Return the number of processes waiting for semaphore number semnum's value to become greater than its current value.
1.220 + GETZCNT Return the number of processes waiting for semaphore number semnum's value to become 0.
1.221 + GETALL Fetch the value of all of the semaphores in the set into the
1.222 + array pointed to by arg.array.
1.223 + SETALL Set the values of all of the semaphores in the set to the values
1.224 + in the array pointed to by arg.array. Outstanding adjust on exit values for all semaphores in this set,
1.225 + in any process are cleared.
1.226 +
1.227 +@endcode
1.228 + The semctl system call
1.229 +performs the operation indicated by cmd on the semaphore set indicated by semid. A fourth argument, a union semun arg ,
1.230 +is required for certain values of cmd. For the commands that use the arg argument, union semun is defined as follows:
1.231 +@code
1.232 +union semun {
1.233 + int val; /* value for SETVAL */
1.234 + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
1.235 + u_short *array; /* array for GETALL & SETALL */
1.236 +};
1.237 +@endcode
1.238 +
1.239 + Commands are performed as follows:
1.240 +
1.241 + @code
1.242 +
1.243 +IPC_STAT Fetch the semaphore sets struct semid_ds ,
1.244 +storing it in the memory pointed to by arg.buf .
1.245 +IPC_SET Changes the sem_perm.uid, sem_perm.gid, and sem_perm.mode members of the semaphore sets struct semid_ds to match those of the struct pointed to by arg.buf.
1.246 +IPC_RMID Immediately removes the semaphore set from the system.
1.247 +
1.248 +@endcode
1.249 +
1.250 +The calling process's uid must equal the semaphore sets sem_perm.uid or sem_perm.cuid, GETVAL Return the value of semaphore number semnum. SETVAL Set the value of semaphore number semnum to arg.val. Outstanding adjust on exit values for this semaphore in any process
1.251 +are cleared.
1.252 +
1.253 +@code
1.254 +
1.255 +GETPID Return the pid of the last process to perform an operation on
1.256 +semaphore number semnum.
1.257 +GETNCNT Return the number of processes waiting for semaphore number semnum's value to become greater than its current value.
1.258 +GETZCNT Return the number of processes waiting for semaphore number semnum s value to become 0.
1.259 +GETALL Fetch the value of all of the semaphores in the set into the
1.260 +array pointed to by arg.array.
1.261 +SETALL Set the values of all of the semaphores in the set to the values
1.262 +in the array pointed to by arg.array. Outstanding adjust on exit values for all semaphores in this set,
1.263 +in any process are cleared.
1.264 +
1.265 +@endcode
1.266 +
1.267 + The struct semid_ds
1.268 +is defined as follows:
1.269 +@code
1.270 +struct semid_ds {
1.271 + struct ipc_perm sem_perm; /* operation permission struct */
1.272 + struct sem *sem_base; /* pointer to first semaphore in set */
1.273 + u_short sem_nsems; /* number of sems in set */
1.274 + time_t sem_otime; /* last operation time */
1.275 + long sem_pad1; /* SVABI/386 says I need this here */
1.276 + time_t sem_ctime; /* last change time */
1.277 + /* Times measured in secs since */
1.278 + /* 00:00:00 GMT, Jan. 1, 1970 */
1.279 + long sem_pad2; /* SVABI/386 says I need this here */
1.280 + long sem_pad3[4]; /* SVABI/386 says I need this here */
1.281 +};
1.282 +@endcode
1.283 +
1.284 +Examples:
1.285 +@code
1.286 +#include <sys/ipc.h>
1.287 +#include <sys/sem.h>
1.288 +#include <stdio.h>
1.289 +#include <errno.h>
1.290 +
1.291 +#define SEM_SET_KEY 1000
1.292 +#define NO_OF_SEMAPHORES 2
1.293 +
1.294 +int main(void)
1.295 +{
1.296 + int sem_set_id;
1.297 + union semun sem_val;
1.298 + /*
1.299 + * Create 2 semaphores in a set, with access only to
1.300 + * the owner
1.301 + */
1.302 + if((sem_set_id = semget(SEM_SET_KEY, NO_OF_SEMAPHORES, IPC_CREAT | 0600))
1.303 + == -1) {
1.304 + printf("Semaphore creation failed with errno %d", errno);
1.305 + return -1;
1.306 + }
1.307 + /*
1.308 + * Initialize the first semaphore in our set to 1
1.309 + */
1.310 + sem_val.array = NULL;
1.311 + sem_val.buf = NULL;
1.312 + sem_val.val = 1;
1.313 + if(semctl(sem_set_id, 0, SETVAL, sem_val) == -1) {
1.314 + printf("Could not initialize first semaphore (errno %d)", errno);
1.315 + return -1;
1.316 + }
1.317 + /*
1.318 + * Initialize the second semaphore in our set to 0
1.319 + */
1.320 + sem_val.val = 0;
1.321 + if(semctl(sem_set_id, 1, SETVAL, sem_val) == -1) {
1.322 + printf("Could not initialize second semaphore (errno %d)", errno);
1.323 + return -1;
1.324 + }
1.325 + /*
1.326 + * Delete the semaphore set
1.327 + */
1.328 + if(semctl(sem_set_id, NO_OF_SEMAPHORES, IPC_RMID) == -1) {
1.329 + printf("Could not delete semaphore set (errno %d)", errno);
1.330 + return -1;
1.331 + }
1.332 + return 0;
1.333 +}
1.334 +
1.335 +@endcode
1.336 +@see semget()
1.337 +@see semop()
1.338 +
1.339 +
1.340 +
1.341 +
1.342 +@publishedAll
1.343 +@externallyDefinedApi
1.344 +*/
1.345 +
1.346 +
1.347 +
1.348 +/** @struct semid_ds
1.349 +
1.350 +Contains following members,
1.351 +
1.352 +@publishedAll
1.353 +@externallyDefinedApi
1.354 +*/
1.355 +
1.356 +/** @var semid_ds::sem_perm
1.357 +operation permission struct
1.358 +*/
1.359 +
1.360 +/** @var semid_ds::sem_base
1.361 +pointer to first semaphore in set
1.362 +*/
1.363 +
1.364 +/** @var semid_ds::sem_nsems
1.365 +number of sems in set
1.366 +*/
1.367 +
1.368 +/** @var semid_ds::sem_otime
1.369 +last operation time
1.370 +*/
1.371 +
1.372 +/** @var semid_ds::sem_pad1
1.373 +SVABI or 386 says I need this here
1.374 +*/
1.375 +
1.376 +/** @var semid_ds::sem_ctime
1.377 +last change time
1.378 +*/
1.379 +
1.380 +/** @var semid_ds::sem_pad2
1.381 +SVABI or 386 says I need this here
1.382 +*/
1.383 +
1.384 +/** @var semid_ds::sem_pad3
1.385 +SVABI or 386 says I need this here
1.386 +*/
1.387 +
1.388 +
1.389 +/** @struct sembuf
1.390 +
1.391 +semop's sops parameter structure
1.392 +
1.393 +@publishedAll
1.394 +@externallyDefinedApi
1.395 +*/
1.396 +
1.397 +/** @var sembuf::sem_num
1.398 +semaphore X
1.399 +*/
1.400 +
1.401 +/** @var sembuf::sem_op
1.402 +semaphore operation
1.403 +*/
1.404 +
1.405 +/** @var sembuf::sem_flg
1.406 +operation flags
1.407 +*/
1.408 +
1.409 +/** @struct sem
1.410 +
1.411 +sem includes following members,
1.412 +
1.413 +@publishedAll
1.414 +@externallyDefinedApi
1.415 +*/
1.416 +
1.417 +/** @var sem::semval
1.418 +semaphore value
1.419 +*/
1.420 +
1.421 +/** @var sem::sempid
1.422 +process ID of last operation
1.423 +*/
1.424 +
1.425 +/** @var sem::semncnt
1.426 +number of processes waiting for semval to become greater than current value
1.427 +*/
1.428 +
1.429 +/** @var sem::semzcnt
1.430 +number of processes waiting for semval to become 0
1.431 +*/
1.432 +
1.433 +
1.434 +/** @def GETNCNT
1.435 +
1.436 +commands for semctl. Return the value of semncnt.
1.437 +
1.438 +@publishedAll
1.439 +@externallyDefinedApi
1.440 +*/
1.441 +
1.442 +/** @def GETPID
1.443 +
1.444 +commands for semctl. Return the value of sempid
1.445 +
1.446 +@publishedAll
1.447 +@externallyDefinedApi
1.448 +*/
1.449 +
1.450 +/** @def GETVAL
1.451 +
1.452 +commands for semctl. Return the value of semval.
1.453 +
1.454 +@publishedAll
1.455 +@externallyDefinedApi
1.456 +*/
1.457 +
1.458 +/** @def GETALL
1.459 +
1.460 +commands for semctl. Return semvals into arg.array
1.461 +
1.462 +@publishedAll
1.463 +@externallyDefinedApi
1.464 +*/
1.465 +
1.466 +/** @def GETZCNT
1.467 +
1.468 +commands for semctl. Return the value of semzcnt.
1.469 +
1.470 +@publishedAll
1.471 +@externallyDefinedApi
1.472 +*/
1.473 +
1.474 +/** @def SETVAL
1.475 +
1.476 +commands for semctl. Set the value of semval to arg.val.
1.477 +
1.478 +@publishedAll
1.479 +@externallyDefinedApi
1.480 +*/
1.481 +
1.482 +/** @def SETALL
1.483 +
1.484 +commands for semctl. Set semvals from arg.array.
1.485 +
1.486 +@publishedAll
1.487 +@externallyDefinedApi
1.488 +*/
1.489 +
1.490 +