Home

GEONius.com
6-Jan-2004
E-mail

sem_util - Semaphore Utilities

The SEM utilities provide a high-level interface to the underlying operating system's semaphore facility.

Creating a semaphore (or accessing an existing semaphore) is as simple as this:

    #include  "sem_util.h"			-- Semaphore utilities.
    Semaphore  semaphore ;
    ...
    sem_create ("name", N, &semaphore) ;
    ...
where N is the initial number of resources being guarded by the semaphore. For example, a mutex semaphore guarding a critical region would have an initial value of 1. A semaphore guarding a pool of 5 buffers would have an initial value of 5.

A process gains access to a guarded resource by "taking" its semaphore; the process is suspended until access to the resource is granted. When the process is finished with the resource, it "gives" the resource back to the semaphore, thereby allowing other processes to access the resource:

    if (!sem_take (semaphore, -1.0)) {		-- Wait for access.
        ... access guarded resource ...
        sem_give (semaphore) ;			-- Relinquish access.
    } else {
        ... error ...
    }
A process can limit the amount of time it will wait for access to a resource by specifying a timeout in the sem_take() call:

    if (!sem_take (semaphore, 5.0)) {		-- Wait 5 seconds for access.
        ... access guarded resource ...
        sem_give (semaphore) ;			-- Relinquish access.
    } else if (errno == EWOULDBLOCK) {
        ... timeout ...
    } else {
        ... error ...
    }
When a semaphore is no longer needed by a process, it should be deleted:

    sem_delete (semaphore) ;
The semaphore isn't actually deleted from the system until the last process using it deletes it.


Implementation Notes (UNIX)

The UNIX semaphore functions, semget(2) et al, are used to create and access semaphores. The name/IPC identifier mappings and reference counts are stored in the named object database (see nob_util.c).

Timeouts in the sem_take() call are not supported under UNIX. I used to have a semaphore utility that polled its semaphore once a second, but, without getting in line, a polling process could conceivably never get the semaphore.

Processes should delete all semaphores before exiting; if a process exits prematurely, the named object database could be left in an inconsistent state.


Implementation Notes (VxWorks)

The SEM semaphores are counting semaphores (see semCLib(1)); under VxMP, the semaphore are visible to other CPUs (see semSmLib(1)). The name/identifier mappings and reference counts are stored in the named object database (see nob_util.c).

Timeouts in the sem_take() call are supported. Note that the timeout error code returned by the VxWorks system call is converted into an EWOULDBLOCK error code.

Processes should delete all semaphores before exiting; if a process exits prematurely, the named object database could be left in an inconsistent state.


Public Procedures

sem_create() - creates a semaphore.
sem_delete() - deletes a semaphore.
sem_give() - releases a semaphore.
sem_id() - returns the IPC identifier for a semaphore.
sem_take() - waits for and holds a semaphore.
sem_value() - returns the value of a semaphore.

Source Files

sem_util.c
sem_util.h

(See libgpl for the complete source, including support routines and build files.)


Alex Measday  /  E-mail