Oberon ||
Library ||
Module Index ||
Search Engine ||
Definition ||
Module
Ulm's Oberon Library:
Semaphores
NAME
Semaphores - general interface for semaphores
SYNOPSIS
TYPE Semaphore = POINTER TO SemaphoreRec;
TYPE SemaphoreRec = RECORD (Disciplines.ObjectRec) END;
TYPE SemaOp = PROCEDURE (sema: Semaphore);
TYPE StatusProc = PROCEDURE (sema: Semaphore) : INTEGER;
TYPE GetConditionProc = PROCEDURE (sema: Semaphore;
VAR condition: Conditions.Condition);
TYPE DropProc = PROCEDURE (condition: Conditions.Condition);
TYPE Interface = POINTER TO InterfaceRec;
TYPE InterfaceRec =
RECORD
p: SemaOp; (* optional: may be NIL *)
v: SemaOp;
getcondition: GetConditionProc;
drop: DropProc;
status: StatusProc;
END;
PROCEDURE Init(sema: Semaphore; if: Interface);
PROCEDURE P(sema: Semaphore);
PROCEDURE V(sema: Semaphore);
PROCEDURE GetCondition(sema: Semaphore; VAR condition: Conditions.Condition);
PROCEDURE Drop(condition: Conditions.Condition);
PROCEDURE Status(sema: Semaphore) : INTEGER;
DESCRIPTION
Semaphores
provides an interface for semaphores.
Semaphores are used for synchronization where multiple processes
want to share common accessible resources.
If the number of resources equals one, semaphores may be used
to assure mutual exclusion if several processes possibly access
the same data structure.
Init
initializes a newly created semaphore and
associates it with the given interface if.
The interface procedures are expected to meet the
specifications following:
- p: PROCEDURE(sema: Semaphore);
-
block the current task until one of the resources becomes free
and allocate it.
This interface procedure is optional
(i.e. it may be set to NIL)
because it may be replaced by getcondition and
Tasks.WaitFor.
It is provided, however,
to allow to avoid Tasks.WaitFor
if one of the resources is already free.
- v: PROCEDURE(sema: Semaphore);
-
free one of the claimed resources.
- status: PROCEDURE() : INTEGER;
-
return the number of free resources, or, if zero,
the negated number of processes which wait for this resource
to become available.
- getcondition: PROCEDURE(sema: Semaphore; VAR condition: Conditions.Condition);
-
create a condition which allows to wait for one of the resources.
The condition must not only indicate the availability of the resource
but has to claim it.
- drop: PROCEDURE(condition: Conditions.Condition);
-
remove the condition from the list of waiting conditions,
or, release the resource if it has already has been claimed.
P
and
V
realize Dijkstra's semaphore operations which claim and release
a resource.
GetCondition
returns a condition which evaluates to TRUE when the
resource has been claimed.
Note that the condition returned by GetCondition
does not indicate the availability of the resource only but claims
the resource itself, i.e. P must not be called additionally
if Conditions.TestCondition returns TRUE.
For this reason conditions may not be recycled,
i.e. for each new try to claim a resource a new condition has to be created.
To undo GetCondition, Drop may be called.
Drop either unqueues the condition from the list of
conditions waiting for one of the resource becoming available,
or releases the resource if it was already claimed by the condition.
Status
reports the current status of sema.
If positive, the returned value indicates the number of free resources.
If less or equal to zero, the absolute value of the returned number
gives the number of processes which waits for the resource to become
available.
DIAGNOSTICS
Semaphores does not produce itself any diagnostics.
Implementations are expected to relate any error events to the semaphore.
For external semaphores (i.e. those which are maintained outside)
it is wise to setup an event queue for the semaphore and
to check for pending events after P operations for lost resources.
Following runtime tests are performed by assertions:
- Init
checks the validity of the interface record.
- Drop
verifies that the condition has been returned formerly by GetCondition.
CAVEAT
Critical regions which are threatened by asynchronous interrupts,
(i.e. which are possible reentered during interrupt processing)
must be also protected by use of the priority system to assure
avoidance of dead locks.
The general pattern for these cases looks as following:
Events.AssertPriority(Priorities.interrupts);
Semaphores.P(mutex);
(* ... critical region ... *)
Semaphores.V(mutex);
Events.ExitPriority;
SEE ALSO
- Events
-
priority system
- LocalSemaphores
-
implementation of internal semaphores
- RelatedEvents
-
setup of event queues
BUGS
Neither Semaphores nor its implementations are able to
check whether P and V operations are properly nested.
Edited by: borchert, last change: 1997/07/11, revision: 1.4, converted to HTML: 1997/07/11
Oberon ||
Library ||
Module Index ||
Search Engine ||
Definition ||
Module