The following example provides a possible structure on which to build an ALGOL program using the EVENT_STATUS entry point of the MCPSUPPORT library.
The EVENT_STATUS function is exported from the operating system as an unprotected REAL function that, when given an event, returns the following information. All undefined bits are zero.
|
Bits |
Meaning |
|
[42:39] |
Lock owner, if event is unavailable |
|
[ 3: 2] |
Event usage: 0 = Normal event 1 = Event reserved for use by operating system 2 = Interrupt attached to event 3 = Event reserved for use by operating system |
|
[ 1: 1] |
Event unavailable (procured) |
|
[ 0: 1] |
Event happened (caused) |
Using the EVENT_STATUS function is the only safe means of finding the owner of an event. The value returned in the Lock Owner field is the same kind of value that is returned by the PROCESSID function. In fact, if the task that owns the lock referenced the PROCESSID function, the value returned would be the same as the value in the Lock Owner field. UNSAFE NEWP programs that manipulate events directly should be avoided since different systems use varying event formats.
BEGIN
TASK TASKA, TASKB;
REAL STACKA, STACKB, EVSTATUS;
EVENT XYZ_LOCK;
%THE FOLLOWING DECLARATIONS MAKE IT POSSIBLE TO USE THE EVENT_STATUS
%FUNCTION IN AN ALGOL PROGRAM. NOTE THAT THE LIBACCESS ATTRIBUTE IS
%EQUAL TO BYFUNCTION.
LIBRARY MCPSUPPORT (LIBACCESS = BYFUNCTION);
REAL PROCEDURE EVENT_STATUS (EV);
EVENT EV;
LIBRARY MCPSUPPORT;
% THE FIELDS FOR EVENT_STATUS RESULT ARE:
DEFINE ES_OWNERSTACKF = [42:39]#,
ES_EVENTUSAGEF = [3:2]#,
ES_UNAVAILABLEF = [1:1]#,
ES_HAPPENEDF = [0:1]#;
PROCEDURE A;
BEGIN
STACKA := PROCESSID;
PROCURE(XYZ_LOCK);
LIBERATE(XYZ_LOCK);
END;
PROCEDURE B;
BEGIN
STACKB := PROCESSID;
PROCURE(XYZ_LOCK);
LIBERATE(XYZ_LOCK);
END;
PROCESS A [TASKA];
PROCESS B [TASKB];
EVSTATUS := EVENT_STATUS(XYZ_LOCK);
IF EVSTATUS.ES_OWNERSTACKF = STACKA THEN
BEGIN
% XYZ_LOCK WAS OWNED BY TASKA AT THE TIME
% THE EVENT_STATUS CALL WAS MADE.
END
ELSE
IF EVSTATUS.ES_OWNERSTACKF = STACKB THEN
BEGIN
% XYZ_LOCK WAS OWNED BY TASKB AT THE TIME
% THE EVENT_STATUS CALL WAS MADE.
END;
WHILE (TASKA.STATUS > VALUE(TERMINATED))
AND (TASKB.STATUS > VALUE(TERMINATED)) DO
WAITANDRESET(MYSELF.EXCEPTIONEVENT);
END.
