Oberon || Library || Module Index || Search Engine || Definition || Module
TYPE Domain = POINTER TO DomainRec; TYPE DomainRec = RECORD (Disciplines.ObjectRec) END; TYPE Condition = POINTER TO ConditionRec; TYPE ConditionRec = RECORD (Disciplines.ObjectRec) END; TYPE ConditionSet = POINTER TO ConditionSetRec; TYPE ConditionSetRec = RECORD (Objects.ObjectRec) END; CONST select = 0; timelimit = 1; async = 2; timecond = 3; preconditions = 4; TYPE CapabilitySet = SET; (* OF [select..preconditions] *) TYPE SelectProc = PROCEDURE (domain: Domain; conditionSet: ConditionSet; time: Times.Time; VAR setOfTrueConditions: ConditionSet; errors: RelatedEvents.Object; retry: BOOLEAN; VAR interrupted: BOOLEAN) : BOOLEAN; TYPE TestProc = PROCEDURE (domain: Domain; condition: Condition; errors: RelatedEvents.Object) : BOOLEAN; TYPE SendEventProc = PROCEDURE (domain: Domain; condition: Condition; event: Events.Event; errors: RelatedEvents.Object) : BOOLEAN; TYPE GetTimeProc = PROCEDURE (domain: Domain; conditionSet: ConditionSet; VAR nextTime: Times.Time; VAR nextCond: Condition; errors: RelatedEvents.Object); TYPE PreConditionsProc = PROCEDURE (domain: Domain; condition: Condition; VAR preconds: ConditionSet; errors: RelatedEvents.Object) : BOOLEAN; TYPE Interface = POINTER TO InterfaceRec; TYPE InterfaceRec = RECORD (Objects.ObjectRec) test: TestProc; select: SelectProc; sendevent: SendEventProc; gettime: GetHintProc; preconditions: PreConditionsProc; END; TYPE Description = POINTER TO DescriptionRec; TYPE DescriptionRec = RECORD (Objects.ObjectRec) caps: CapabilitySet; internal: BOOLEAN; END; TYPE GetTimeOfNextTryProc = PROCEDURE (iteration: INTEGER; VAR time: Times.Time);
PROCEDURE InitDomain(domain: Domain; if: Interface; desc: Description); PROCEDURE Init(condition: Condition; domain: Domain); PROCEDURE WaitFor(conditionSet: ConditionSet; VAR setOfTrueConditions: ConditionSet; errors: RelatedEvents.Object); PROCEDURE Test(condition: Condition; errors: RelatedEvents.Object) : BOOLEAN; PROCEDURE CreateSet(VAR conditionSet: ConditionSet); PROCEDURE Incl(conditionSet: ConditionSet; condition: Condition); PROCEDURE Excl(conditionSet: ConditionSet; condition: Condition); PROCEDURE Union(result: ConditionSet; set: ConditionSet); PROCEDURE Union3(VAR result: ConditionSet; set1, set2: ConditionSet); PROCEDURE In(conditionSet: ConditionSet; condition: Condition) : BOOLEAN; PROCEDURE Card(conditionSet: ConditionSet) : INTEGER; PROCEDURE ExamineConditions(conditionSet: ConditionSet); PROCEDURE GetNextCondition(conditionSet: ConditionSet; VAR condition: Condition) : BOOLEAN; PROCEDURE SetGetTimeOfNextTryProc(p: GetTimeOfNextTryProc);
There exist a couple of condition variants with differing semantics in dependence of the different kinds of events they allow to wait for. These differences do not affect Conditions itself but result in different uses. The most important variants are:
Note that conditions are always created and used locally, i.e. even for non-local events each party creates and uses its own condition. Conditions related to group events and concurrent conditions need some special treatment when they become TRUE. Conditions which are related to local or group events may be recycled.
Note that Conditions is independent from the kind of concurrency used. The synchronization of concurrent units which share the same address space is done by other modules (e.g. Tasks). Conditions itself allows only to block all concurrent units of an address space. Nevertheless, conditions of Conditions may be used for the synchronization with other processes (concurrent units of other address spaces) and with concurrent units of the same address space. For this to work, Conditions requires the memory model to follow the semantics of total store ordering, i.e. memory operations are visible for all concurrent units of the same address space in the order of execution.
Conditions which are of the same type (and generally defined by one module) belong to one domain. An interface is associated with a domain and some of the interface procedures are able to cope with a set of conditions which all belong to the same domain.
Interfaces are expected to meet following specifications:
InitDomain initializes a new domain and associates it with the interface if and the given description desc. The description consists of the capability set and a boolean-valued component internal which states whether the value of conditions of the given domain may change during process suspension (i.e. call of Process.Pause). Internal conditions are able change only if the program is running while external conditions may be effected by the outside world. Init initializes a condition and connects it to the given domain.
WaitFor blocks the current process until at least one of the conditions becomes TRUE and returns the set of true conditions in conditionSet. Note that usually Tasks.WaitFor is called which blocks the current task only.
The algorithm of WaitFor may degenerate in some cases to a busy loop, i.e. the conditions are repeatedly tested. To reduce the consumed CPU time in such a case, the process is suspended for some time in each iteration of the busy loop. The delay time of this loop for the n-th retry may be determined by an interface procedure which is to be passed to SetGetTimeOfNextTryProc. Initially, this interface procedure is provided by Conditions itself with a reasonable variant which returns longer delay times for increasing n. Busy loops may be caused by external conditions which do not support the capabilities async or timelimit.
Test returns TRUE if condition evaluates to TRUE.
CreateSet creates and initializes a condition set to the empty set. Incl includes condition to conditionSet. Excl excludes condition from conditionSet. Union stores in result the union of result and set. Union3 returns in result the union of set1 and set2. In returns TRUE if condition is a member of conditionSet. Card returns the cardinality of conditionSet.
ExamineConditions starts a traverse through all conditions of conditionSet. GetNextCondition, if successful, stores one of the conditions of conditionSet into condition and returns FALSE if there are no more conditions.
Conditions does not generate any error events itself but forwards the events generated by the interface procedures to the errors parameters.
Oberon || Library || Module Index || Search Engine || Definition || Module