os/ossrv/genericopenlibs/openenvcore/include/sys/sem.dosc
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /** @file  ../include/sys/sem.h
     2 @internalComponent
     3 */
     4 
     5 /** @fn  semget(key_t key, int nsems, int semflg)
     6 @param key
     7 @param nsems
     8 @param semflg
     9 @return   The semget call
    10 returns the id of a semaphore set if successful; otherwise, -1
    11 is returned and errno is set to indicate the error.
    12 
    13 @code
    14  SEM_R Read access for user.
    15  SEM_A Alter access for user.
    16  ( SEM_R>>3 )
    17   Read access for group.
    18  ( SEM_A>>3 )
    19   Alter access for group.
    20  ( SEM_R>>6 )
    21   Read access for other.
    22  ( SEM_A>>6 )
    23   Alter access for other.
    24 
    25 Note:The 'group' flags (SEM_R >> 3 and SEM_A >> 3) are ignored in Symbian OS.
    26 @endcode
    27   Based on the values of key and semflg, semget returns the identifier of a newly created or previously existing
    28 set of semaphores. The key
    29 is analogous to a filename: it provides a handle that names an
    30 IPC object.
    31 There are three ways to specify a key: IPC_PRIVATE may be specified, in which case a new IPC object
    32 will be created. An integer constant may be specified.
    33 If no IPC object corresponding
    34 to key is specified and the IPC_CREAT bit is set in semflg, a new one will be created. The ftok function
    35 may be used to generate a key from a pathname.
    36 
    37 @code
    38 
    39  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.
    40 @endcode
    41 
    42 
    43  If a new set of semaphores is being created, nsems is used to indicate the number of semaphores the set should contain.
    44 Otherwise, nsems may be specified as 0.
    45 
    46 Examples:
    47 @code
    48 #include <sys/ipc.h>
    49 #include <sys/sem.h>
    50 #include <stdio.h>
    51 #include <errno.h>
    52 
    53 #define SEM_SET_KEY 1000
    54 #define NO_OF_SEMAPHORES 2
    55 
    56 int main(void)
    57 {
    58     int sem_set_id;
    59     int perm;
    60     /*
    61      * Create 2 semaphores in a set, with access only to
    62      * the owner
    63      */
    64     perm = SEM_R | SEM_A;
    65     if((sem_set_id = semget(SEM_SET_KEY, NO_OF_SEMAPHORES, IPC_CREAT | perm))
    66         == -1) {
    67        printf("Semaphore creation failed with errno %d", errno);
    68        return -1;
    69     }
    70     return 0;
    71 }
    72 @endcode
    73 
    74 @code
    75 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.
    76 e.g The value of the variable perm used in the above example code should be as below
    77 perm = SEM_R | SEM_A | SEM_R >> 6 | SEM_A >> 6
    78 @endcode
    79 
    80 @see semctl()
    81 @see semop()
    82 @see ftok()
    83 
    84 
    85  
    86 
    87 @publishedAll
    88 @externallyDefinedApi
    89 */
    90 
    91 /** @fn  semop(int semid, struct sembuf *sops, unsigned nsops)
    92 @param semid
    93 @param sops
    94 @param nsops
    95 @return   The semop function returns 0 if successful; otherwise the
    96 value -1 is returned and errno is set to indicate the error.
    97 
    98   The semop system call
    99 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 ,
   100 which is defined as follows: 
   101 
   102 @code
   103 struct sembuf {
   104         u_short sem_num;        /* semaphore # */
   105         short   sem_op;         /* semaphore operation */
   106         short   sem_flg;        /* operation flags */
   107 };
   108 @endcode
   109 
   110  For each element in array, sem_op and sem_flg determine an operation to be performed on semaphore number sem_num in the set.
   111 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.
   112 
   113  The operation performed depends as follows on the value of sem_op: When sem_op is positive and the process has alter permission,
   114 the semaphore's value is incremented by sem_op's value.
   115 If SEM_UNDO is specified, the semaphore's adjust on exit value is decremented by sem_op's value.
   116 A positive value for sem_op generally corresponds to a process releasing a resource
   117 associated with the semaphore. The behavior when sem_op is negative and the process has alter permission,
   118 depends on the current value of the semaphore: If the current value of the semaphore is greater than or equal to
   119 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
   120 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
   121 conditions is satisfied: Some other process removes the semaphore with the IPC_RMID option of semctl .
   122 In this case, semop returns immediately with a return value of EIDRM. The semaphore's
   123 value is greater than or equal to the absolute value of sem_op. When this condition becomes true, the semaphore's value is decremented
   124 by the absolute value of sem_op, the semaphore's adjust on exit value is incremented by the
   125 absolute value of sem_op.
   126 
   127  A negative value for sem_op generally means that a process is waiting for a resource to become
   128 available. When sem_op is zero and the process has read permission,
   129 one of the following will occur: If the current value of the semaphore is equal to zero
   130 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
   131 conditions is satisfied: Some other process removes the semaphore with the IPC_RMID option of semctl .
   132 In this case, semop returns immediately with a return value of EIDRM. The semaphore's value becomes zero.
   133 
   134  For each semaphore a process has in use, an "adjust on exit"
   135 value is maintained, as alluded to earlier.
   136 When a process
   137 exits, either voluntarily or involuntarily, the adjust on exit value
   138 for each semaphore is added to the semaphore's value.
   139 This can
   140 be used to insure that a resource is released if a process terminates
   141 unexpectedly.
   142 
   143 Examples:
   144 @code
   145 #include <sys/ipc.h>
   146 #include <sys/sem.h>
   147 #include <stdio.h>
   148 
   149 void File_Update(char* path, int val)
   150 {
   151     struct sembuf sem_op;
   152     FILE* fp;
   153     /*
   154      * Wait on the semaphore till the value is non-negative.
   155      */
   156     sem_op.sem_num = 0;
   157     sem_op.sem_op = -1;
   158     sem_op.sem_flg = 0;
   159     semop(sem_set_id, &sem;_op, 1);
   160     /*
   161      * If we are here, then We have locked the semaphore,
   162      * and are assured exclusive access to file.
   163      * We can now manipulate the file
   164      */
   165     fp = fopen(path, "w");
   166     if (fp) {
   167         fprintf(fp, "%d", val);
   168         fclose(fp);
   169     }
   170     /*
   171      * Increase the value of the semaphore by 1 so that others blocked on
   172      * this semaphore get awakened.
   173      */
   174     sem_op.sem_num = 0;
   175     sem_op.sem_op = 1;
   176     sem_op.sem_flg = 0;
   177     semop(sem_set_id, &sem;_op, 1);
   178 }
   179 
   180 @endcode
   181 @see semctl()
   182 @see semget()
   183 
   184 
   185 Bugs:
   186 
   187  The semop system call
   188 may block waiting for memory even if IPC_NOWAIT was specified. 
   189 
   190  
   191 
   192 @publishedAll
   193 @externallyDefinedApi
   194 */
   195 
   196 /** @fn  semctl(int semid, int semnum, int cmd, ...)
   197 @param semid
   198 @param semnum
   199 @param cmd
   200 @param ...
   201 @return   On success, when cmd is one of GETVAL, GETPID, GETNCNT or GETZCNT, semctl returns the corresponding value; otherwise, 0 is returned.
   202 On failure, -1 is returned, and errno is set to indicate the error.
   203 
   204 @code
   205  IPC_STAT Fetch the semaphore sets struct semid_ds ,
   206  storing it in the memory pointed to by arg.buf .
   207  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.
   208  IPC_RMID Immediately removes the semaphore set from the system.
   209  The calling
   210  processe'ss uid must equal the semaphore sets sem_perm.uid or sem_perm.cuid,
   211  GETVAL Return the value of semaphore number semnum.
   212  SETVAL Set the value of semaphore number semnum to arg.val. Outstanding adjust on exit values for this semaphore in any process
   213  are cleared.
   214  GETPID Return the pid of the last process to perform an operation on
   215  semaphore number semnum.
   216  GETNCNT Return the number of processes waiting for semaphore number semnum's value to become greater than its current value.
   217  GETZCNT Return the number of processes waiting for semaphore number semnum's value to become 0.
   218  GETALL Fetch the value of all of the semaphores in the set into the
   219  array pointed to by arg.array.
   220  SETALL Set the values of all of the semaphores in the set to the values
   221  in the array pointed to by arg.array. Outstanding adjust on exit values for all semaphores in this set,
   222  in any process are cleared.
   223 
   224 @endcode
   225   The semctl system call
   226 performs the operation indicated by cmd on the semaphore set indicated by semid. A fourth argument, a union semun arg ,
   227 is required for certain values of cmd. For the commands that use the arg argument, union semun is defined as follows: 
   228 @code
   229 union semun {
   230         int     val;            /* value for SETVAL */
   231         struct  semid_ds *buf;  /* buffer for IPC_STAT & IPC_SET */
   232         u_short *array;         /* array for GETALL & SETALL */
   233 };
   234 @endcode
   235 
   236  Commands are performed as follows: 
   237  
   238  @code
   239  
   240 IPC_STAT Fetch the semaphore sets struct semid_ds ,
   241 storing it in the memory pointed to by arg.buf . 
   242 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. 
   243 IPC_RMID Immediately removes the semaphore set from the system.
   244 
   245 @endcode
   246 
   247 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
   248 are cleared. 
   249 
   250 @code
   251 
   252 GETPID Return the pid of the last process to perform an operation on
   253 semaphore number semnum. 
   254 GETNCNT Return the number of processes waiting for semaphore number semnum's value to become greater than its current value. 
   255 GETZCNT Return the number of processes waiting for semaphore number semnum s value to become 0. 
   256 GETALL Fetch the value of all of the semaphores in the set into the
   257 array pointed to by arg.array. 
   258 SETALL Set the values of all of the semaphores in the set to the values
   259 in the array pointed to by arg.array. Outstanding adjust on exit values for all semaphores in this set,
   260 in any process are cleared.
   261 
   262 @endcode
   263 
   264  The struct semid_ds
   265 is defined as follows: 
   266 @code
   267 struct semid_ds {
   268         struct  ipc_perm sem_perm;      /* operation permission struct */
   269         struct  sem *sem_base;  /* pointer to first semaphore in set */
   270         u_short sem_nsems;      /* number of sems in set */
   271         time_t  sem_otime;      /* last operation time */
   272         long    sem_pad1;       /* SVABI/386 says I need this here */
   273         time_t  sem_ctime;      /* last change time */
   274                                 /* Times measured in secs since */
   275                                 /* 00:00:00 GMT, Jan. 1, 1970 */
   276         long    sem_pad2;       /* SVABI/386 says I need this here */
   277         long    sem_pad3[4];    /* SVABI/386 says I need this here */
   278 };
   279 @endcode
   280 
   281 Examples:
   282 @code
   283 #include <sys/ipc.h>
   284 #include <sys/sem.h>
   285 #include <stdio.h>
   286 #include <errno.h>
   287 
   288 #define SEM_SET_KEY 1000
   289 #define NO_OF_SEMAPHORES 2
   290 
   291 int main(void)
   292 {
   293     int sem_set_id;
   294     union semun sem_val;
   295     /*
   296      * Create 2 semaphores in a set, with access only to
   297      * the owner
   298      */
   299     if((sem_set_id = semget(SEM_SET_KEY, NO_OF_SEMAPHORES, IPC_CREAT | 0600))
   300         == -1) {
   301        printf("Semaphore creation failed with errno %d", errno);
   302        return -1;
   303     }
   304     /*
   305      * Initialize the first semaphore in our set to 1
   306      */
   307     sem_val.array = NULL;
   308     sem_val.buf = NULL;
   309     sem_val.val = 1;
   310     if(semctl(sem_set_id, 0, SETVAL, sem_val) == -1) {
   311        printf("Could not initialize first semaphore (errno %d)", errno);
   312        return -1;
   313     }
   314     /*
   315      * Initialize the second semaphore in our set to 0
   316      */
   317     sem_val.val = 0;
   318     if(semctl(sem_set_id, 1, SETVAL, sem_val) == -1) {
   319        printf("Could not initialize second semaphore (errno %d)", errno);
   320        return -1;
   321     }
   322     /*
   323      * Delete the semaphore set
   324      */
   325     if(semctl(sem_set_id, NO_OF_SEMAPHORES, IPC_RMID) == -1) {
   326        printf("Could not delete semaphore set (errno %d)", errno);
   327        return -1;
   328     }
   329     return 0;
   330 }
   331 
   332 @endcode
   333 @see semget()
   334 @see semop()
   335 
   336 
   337  
   338 
   339 @publishedAll
   340 @externallyDefinedApi
   341 */
   342 
   343 
   344 
   345 /** @struct semid_ds
   346 
   347 Contains following members,
   348 
   349 @publishedAll
   350 @externallyDefinedApi
   351 */
   352 
   353 /** @var semid_ds::sem_perm
   354 operation permission struct
   355 */
   356 
   357 /** @var semid_ds::sem_base
   358 pointer to first semaphore in set
   359 */
   360 
   361 /** @var semid_ds::sem_nsems
   362 number of sems in set
   363 */
   364 
   365 /** @var semid_ds::sem_otime
   366 last operation time
   367 */
   368 
   369 /** @var semid_ds::sem_pad1
   370 SVABI or 386 says I need this here 
   371 */
   372 
   373 /** @var semid_ds::sem_ctime
   374 last change time
   375 */
   376 
   377 /** @var semid_ds::sem_pad2
   378 SVABI or 386 says I need this here
   379 */
   380 
   381 /** @var semid_ds::sem_pad3
   382 SVABI or 386 says I need this here
   383 */
   384 
   385 
   386 /** @struct sembuf
   387 
   388 semop's sops parameter structure
   389 
   390 @publishedAll
   391 @externallyDefinedApi
   392 */
   393 
   394 /** @var sembuf::sem_num
   395 semaphore X
   396 */
   397 
   398 /** @var sembuf::sem_op
   399 semaphore operation
   400 */
   401 
   402 /** @var sembuf::sem_flg
   403 operation flags
   404 */
   405 
   406 /** @struct sem
   407 
   408 sem includes following members,
   409 
   410 @publishedAll
   411 @externallyDefinedApi
   412 */
   413 
   414 /** @var sem::semval
   415 semaphore value
   416 */
   417 
   418 /** @var sem::sempid
   419 process ID of last operation
   420 */
   421 
   422 /** @var sem::semncnt
   423 number of processes waiting for semval to become greater than current value 
   424 */
   425 
   426 /** @var sem::semzcnt
   427 number of processes waiting for semval to become 0 
   428 */
   429 
   430 
   431 /** @def GETNCNT
   432 
   433 commands for semctl. Return the value of semncnt.
   434 
   435 @publishedAll
   436 @externallyDefinedApi
   437 */
   438 
   439 /** @def GETPID
   440 
   441 commands for semctl. Return the value of sempid
   442 
   443 @publishedAll
   444 @externallyDefinedApi
   445 */
   446 
   447 /** @def GETVAL
   448 
   449 commands for semctl. Return the value of semval.
   450 
   451 @publishedAll
   452 @externallyDefinedApi
   453 */
   454 
   455 /** @def GETALL
   456 
   457 commands for semctl. Return semvals into arg.array 
   458 
   459 @publishedAll
   460 @externallyDefinedApi
   461 */
   462 
   463 /** @def GETZCNT
   464 
   465 commands for semctl. Return the value of semzcnt.
   466 
   467 @publishedAll
   468 @externallyDefinedApi
   469 */
   470 
   471 /** @def SETVAL
   472 
   473 commands for semctl. Set the value of semval to arg.val.
   474 
   475 @publishedAll
   476 @externallyDefinedApi
   477 */
   478 
   479 /** @def SETALL
   480 
   481 commands for semctl. Set semvals from arg.array.
   482 
   483 @publishedAll
   484 @externallyDefinedApi
   485 */
   486 
   487