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