99 lines
1.7 KiB
Modula-2
99 lines
1.7 KiB
Modula-2
|
IMPLEMENTATION MODULE Processes [1];
|
||
|
(* This implementation module comes from
|
||
|
"Programming in Modula-2", by Niklaus Wirth,
|
||
|
3rd edition, Springer-Verlag, New York, 1985
|
||
|
*)
|
||
|
|
||
|
FROM SYSTEM IMPORT ADDRESS, TSIZE, NEWPROCESS, TRANSFER;
|
||
|
|
||
|
FROM Storage IMPORT ALLOCATE;
|
||
|
|
||
|
TYPE SIGNAL = POINTER TO ProcessDescriptor;
|
||
|
|
||
|
ProcessDescriptor =
|
||
|
RECORD next: SIGNAL; (* ring *)
|
||
|
queue: SIGNAL; (* queue of waiting processes *)
|
||
|
cor: ADDRESS;
|
||
|
ready: BOOLEAN;
|
||
|
END;
|
||
|
|
||
|
VAR cp: SIGNAL; (* current process *)
|
||
|
|
||
|
PROCEDURE StartProcess(P: PROC; n: CARDINAL);
|
||
|
VAR s0: SIGNAL;
|
||
|
wsp: ADDRESS;
|
||
|
BEGIN
|
||
|
s0 := cp;
|
||
|
ALLOCATE(wsp, n);
|
||
|
ALLOCATE(cp, TSIZE(ProcessDescriptor));
|
||
|
WITH cp^ DO
|
||
|
next := s0^.next;
|
||
|
s0^.next := cp;
|
||
|
ready := TRUE;
|
||
|
queue := NIL
|
||
|
END;
|
||
|
NEWPROCESS(P, wsp, n, cp^.cor);
|
||
|
TRANSFER(s0^.cor, cp^.cor);
|
||
|
END StartProcess;
|
||
|
|
||
|
PROCEDURE SEND(VAR s: SIGNAL);
|
||
|
VAR s0: SIGNAL;
|
||
|
BEGIN
|
||
|
IF s # NIL THEN
|
||
|
s0 := cp;
|
||
|
cp := s;
|
||
|
WITH cp^ DO
|
||
|
s := queue;
|
||
|
ready := TRUE;
|
||
|
queue := NIL
|
||
|
END;
|
||
|
TRANSFER(s0^.cor, cp^.cor);
|
||
|
END
|
||
|
END SEND;
|
||
|
|
||
|
PROCEDURE WAIT(VAR s: SIGNAL);
|
||
|
VAR s0, s1: SIGNAL;
|
||
|
BEGIN
|
||
|
(* insert cp in queue s *)
|
||
|
IF s = NIL THEN
|
||
|
s := cp
|
||
|
ELSE
|
||
|
s0 := s;
|
||
|
s1 := s0^.queue;
|
||
|
WHILE s1 # NIL DO
|
||
|
s0 := s1;
|
||
|
s1 := s0^.queue
|
||
|
END;
|
||
|
s0^.queue := cp
|
||
|
END;
|
||
|
s0 := cp;
|
||
|
REPEAT
|
||
|
cp := cp^.next
|
||
|
UNTIL cp^.ready;
|
||
|
IF cp = s0 THEN
|
||
|
(* deadlock *)
|
||
|
HALT
|
||
|
END;
|
||
|
s0^.ready := FALSE;
|
||
|
TRANSFER(s0^.cor, cp^.cor)
|
||
|
END WAIT;
|
||
|
|
||
|
PROCEDURE Awaited(s: SIGNAL): BOOLEAN;
|
||
|
BEGIN
|
||
|
RETURN s # NIL
|
||
|
END Awaited;
|
||
|
|
||
|
PROCEDURE Init(VAR s: SIGNAL);
|
||
|
BEGIN
|
||
|
s := NIL
|
||
|
END Init;
|
||
|
|
||
|
BEGIN
|
||
|
ALLOCATE(cp, TSIZE(ProcessDescriptor));
|
||
|
WITH cp^ DO
|
||
|
next := cp;
|
||
|
ready := TRUE;
|
||
|
queue := NIL
|
||
|
END
|
||
|
END Processes.
|