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.
|