diff -r 000000000000 -r bde4ae8d615e os/ossrv/genericopenlibs/openenvcore/include/sys/sem.dosc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/genericopenlibs/openenvcore/include/sys/sem.dosc Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,487 @@ +/** @file ../include/sys/sem.h +@internalComponent +*/ + +/** @fn semget(key_t key, int nsems, int semflg) +@param key +@param nsems +@param semflg +@return The semget call +returns the id of a semaphore set if successful; otherwise, -1 +is returned and errno is set to indicate the error. + +@code + 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. + +Note:The 'group' flags (SEM_R >> 3 and SEM_A >> 3) are ignored in Symbian OS. +@endcode + Based on the values of key and semflg, semget returns the identifier of a newly created or previously existing +set of semaphores. The key +is analogous to a filename: it provides a handle that names an +IPC object. +There are three ways to specify a key: IPC_PRIVATE may be specified, in which case a new IPC object +will be created. An integer constant may be specified. +If no IPC object corresponding +to key is specified and the IPC_CREAT bit is set in semflg, a new one will be created. The ftok function +may be used to generate a key from a pathname. + +@code + + 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. +@endcode + + + If a new set of semaphores is being created, nsems is used to indicate the number of semaphores the set should contain. +Otherwise, nsems may be specified as 0. + +Examples: +@code +#include +#include +#include +#include + +#define SEM_SET_KEY 1000 +#define NO_OF_SEMAPHORES 2 + +int main(void) +{ + int sem_set_id; + int perm; + /* + * Create 2 semaphores in a set, with access only to + * the owner + */ + perm = SEM_R | SEM_A; + if((sem_set_id = semget(SEM_SET_KEY, NO_OF_SEMAPHORES, IPC_CREAT | perm)) + == -1) { + printf("Semaphore creation failed with errno %d", errno); + return -1; + } + return 0; +} +@endcode + +@code +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. +e.g The value of the variable perm used in the above example code should be as below +perm = SEM_R | SEM_A | SEM_R >> 6 | SEM_A >> 6 +@endcode + +@see semctl() +@see semop() +@see ftok() + + + + +@publishedAll +@externallyDefinedApi +*/ + +/** @fn semop(int semid, struct sembuf *sops, unsigned nsops) +@param semid +@param sops +@param nsops +@return The semop function returns 0 if successful; otherwise the +value -1 is returned and errno is set to indicate the error. + + The semop system call +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 , +which is defined as follows: + +@code +struct sembuf { + u_short sem_num; /* semaphore # */ + short sem_op; /* semaphore operation */ + short sem_flg; /* operation flags */ +}; +@endcode + + For each element in array, sem_op and sem_flg determine an operation to be performed on semaphore number sem_num in the set. +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. + + The operation performed depends as follows on the value of sem_op: When sem_op is positive and the process has alter permission, +the semaphore's value is incremented by sem_op's value. +If SEM_UNDO is specified, the semaphore's adjust on exit value is decremented by sem_op's value. +A positive value for sem_op generally corresponds to a process releasing a resource +associated with the semaphore. The behavior when sem_op is negative and the process has alter permission, +depends on the current value of the semaphore: If the current value of the semaphore is greater than or equal to +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 +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 +conditions is satisfied: Some other process removes the semaphore with the IPC_RMID option of semctl . +In this case, semop returns immediately with a return value of EIDRM. The semaphore's +value is greater than or equal to the absolute value of sem_op. When this condition becomes true, the semaphore's value is decremented +by the absolute value of sem_op, the semaphore's adjust on exit value is incremented by the +absolute value of sem_op. + + A negative value for sem_op generally means that a process is waiting for a resource to become +available. When sem_op is zero and the process has read permission, +one of the following will occur: If the current value of the semaphore is equal to zero +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 +conditions is satisfied: Some other process removes the semaphore with the IPC_RMID option of semctl . +In this case, semop returns immediately with a return value of EIDRM. The semaphore's value becomes zero. + + For each semaphore a process has in use, an "adjust on exit" +value is maintained, as alluded to earlier. +When a process +exits, either voluntarily or involuntarily, the adjust on exit value +for each semaphore is added to the semaphore's value. +This can +be used to insure that a resource is released if a process terminates +unexpectedly. + +Examples: +@code +#include +#include +#include + +void File_Update(char* path, int val) +{ + struct sembuf sem_op; + FILE* fp; + /* + * Wait on the semaphore till the value is non-negative. + */ + sem_op.sem_num = 0; + sem_op.sem_op = -1; + sem_op.sem_flg = 0; + semop(sem_set_id, &sem;_op, 1); + /* + * If we are here, then We have locked the semaphore, + * and are assured exclusive access to file. + * We can now manipulate the file + */ + fp = fopen(path, "w"); + if (fp) { + fprintf(fp, "%d", val); + fclose(fp); + } + /* + * Increase the value of the semaphore by 1 so that others blocked on + * this semaphore get awakened. + */ + sem_op.sem_num = 0; + sem_op.sem_op = 1; + sem_op.sem_flg = 0; + semop(sem_set_id, &sem;_op, 1); +} + +@endcode +@see semctl() +@see semget() + + +Bugs: + + The semop system call +may block waiting for memory even if IPC_NOWAIT was specified. + + + +@publishedAll +@externallyDefinedApi +*/ + +/** @fn semctl(int semid, int semnum, int cmd, ...) +@param semid +@param semnum +@param cmd +@param ... +@return On success, when cmd is one of GETVAL, GETPID, GETNCNT or GETZCNT, semctl returns the corresponding value; otherwise, 0 is returned. +On failure, -1 is returned, and errno is set to indicate the error. + +@code + IPC_STAT Fetch the semaphore sets struct semid_ds , + storing it in the memory pointed to by arg.buf . + 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. + IPC_RMID Immediately removes the semaphore set from the system. + The calling + processe'ss 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 + are cleared. + GETPID Return the pid of the last process to perform an operation on + semaphore number semnum. + GETNCNT Return the number of processes waiting for semaphore number semnum's value to become greater than its current value. + GETZCNT Return the number of processes waiting for semaphore number semnum's value to become 0. + GETALL Fetch the value of all of the semaphores in the set into the + array pointed to by arg.array. + SETALL Set the values of all of the semaphores in the set to the values + in the array pointed to by arg.array. Outstanding adjust on exit values for all semaphores in this set, + in any process are cleared. + +@endcode + The semctl system call +performs the operation indicated by cmd on the semaphore set indicated by semid. A fourth argument, a union semun arg , +is required for certain values of cmd. For the commands that use the arg argument, union semun is defined as follows: +@code +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + u_short *array; /* array for GETALL & SETALL */ +}; +@endcode + + Commands are performed as follows: + + @code + +IPC_STAT Fetch the semaphore sets struct semid_ds , +storing it in the memory pointed to by arg.buf . +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. +IPC_RMID Immediately removes the semaphore set from the system. + +@endcode + +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 +are cleared. + +@code + +GETPID Return the pid of the last process to perform an operation on +semaphore number semnum. +GETNCNT Return the number of processes waiting for semaphore number semnum's value to become greater than its current value. +GETZCNT Return the number of processes waiting for semaphore number semnum s value to become 0. +GETALL Fetch the value of all of the semaphores in the set into the +array pointed to by arg.array. +SETALL Set the values of all of the semaphores in the set to the values +in the array pointed to by arg.array. Outstanding adjust on exit values for all semaphores in this set, +in any process are cleared. + +@endcode + + The struct semid_ds +is defined as follows: +@code +struct semid_ds { + struct ipc_perm sem_perm; /* operation permission struct */ + struct sem *sem_base; /* pointer to first semaphore in set */ + u_short sem_nsems; /* number of sems in set */ + time_t sem_otime; /* last operation time */ + long sem_pad1; /* SVABI/386 says I need this here */ + time_t sem_ctime; /* last change time */ + /* Times measured in secs since */ + /* 00:00:00 GMT, Jan. 1, 1970 */ + long sem_pad2; /* SVABI/386 says I need this here */ + long sem_pad3[4]; /* SVABI/386 says I need this here */ +}; +@endcode + +Examples: +@code +#include +#include +#include +#include + +#define SEM_SET_KEY 1000 +#define NO_OF_SEMAPHORES 2 + +int main(void) +{ + int sem_set_id; + union semun sem_val; + /* + * Create 2 semaphores in a set, with access only to + * the owner + */ + if((sem_set_id = semget(SEM_SET_KEY, NO_OF_SEMAPHORES, IPC_CREAT | 0600)) + == -1) { + printf("Semaphore creation failed with errno %d", errno); + return -1; + } + /* + * Initialize the first semaphore in our set to 1 + */ + sem_val.array = NULL; + sem_val.buf = NULL; + sem_val.val = 1; + if(semctl(sem_set_id, 0, SETVAL, sem_val) == -1) { + printf("Could not initialize first semaphore (errno %d)", errno); + return -1; + } + /* + * Initialize the second semaphore in our set to 0 + */ + sem_val.val = 0; + if(semctl(sem_set_id, 1, SETVAL, sem_val) == -1) { + printf("Could not initialize second semaphore (errno %d)", errno); + return -1; + } + /* + * Delete the semaphore set + */ + if(semctl(sem_set_id, NO_OF_SEMAPHORES, IPC_RMID) == -1) { + printf("Could not delete semaphore set (errno %d)", errno); + return -1; + } + return 0; +} + +@endcode +@see semget() +@see semop() + + + + +@publishedAll +@externallyDefinedApi +*/ + + + +/** @struct semid_ds + +Contains following members, + +@publishedAll +@externallyDefinedApi +*/ + +/** @var semid_ds::sem_perm +operation permission struct +*/ + +/** @var semid_ds::sem_base +pointer to first semaphore in set +*/ + +/** @var semid_ds::sem_nsems +number of sems in set +*/ + +/** @var semid_ds::sem_otime +last operation time +*/ + +/** @var semid_ds::sem_pad1 +SVABI or 386 says I need this here +*/ + +/** @var semid_ds::sem_ctime +last change time +*/ + +/** @var semid_ds::sem_pad2 +SVABI or 386 says I need this here +*/ + +/** @var semid_ds::sem_pad3 +SVABI or 386 says I need this here +*/ + + +/** @struct sembuf + +semop's sops parameter structure + +@publishedAll +@externallyDefinedApi +*/ + +/** @var sembuf::sem_num +semaphore X +*/ + +/** @var sembuf::sem_op +semaphore operation +*/ + +/** @var sembuf::sem_flg +operation flags +*/ + +/** @struct sem + +sem includes following members, + +@publishedAll +@externallyDefinedApi +*/ + +/** @var sem::semval +semaphore value +*/ + +/** @var sem::sempid +process ID of last operation +*/ + +/** @var sem::semncnt +number of processes waiting for semval to become greater than current value +*/ + +/** @var sem::semzcnt +number of processes waiting for semval to become 0 +*/ + + +/** @def GETNCNT + +commands for semctl. Return the value of semncnt. + +@publishedAll +@externallyDefinedApi +*/ + +/** @def GETPID + +commands for semctl. Return the value of sempid + +@publishedAll +@externallyDefinedApi +*/ + +/** @def GETVAL + +commands for semctl. Return the value of semval. + +@publishedAll +@externallyDefinedApi +*/ + +/** @def GETALL + +commands for semctl. Return semvals into arg.array + +@publishedAll +@externallyDefinedApi +*/ + +/** @def GETZCNT + +commands for semctl. Return the value of semzcnt. + +@publishedAll +@externallyDefinedApi +*/ + +/** @def SETVAL + +commands for semctl. Set the value of semval to arg.val. + +@publishedAll +@externallyDefinedApi +*/ + +/** @def SETALL + +commands for semctl. Set semvals from arg.array. + +@publishedAll +@externallyDefinedApi +*/ + +