ack/lang/m2/libm2/Processes.mod

104 lines
1.8 KiB
Modula-2
Raw Normal View History

1987-08-19 18:07:01 +00:00
(*$R-*)
1987-05-13 14:36:45 +00:00
IMPLEMENTATION MODULE Processes [1];
1988-02-19 15:54:01 +00:00
(*
Module: Processes
From: "Programming in Modula-2", 3rd, corrected edition, by N. Wirth
Version: $Header$
1987-05-13 14:36:45 +00:00
*)
FROM SYSTEM IMPORT ADDRESS, TSIZE, NEWPROCESS, TRANSFER;
FROM Storage IMPORT ALLOCATE;
1987-06-26 15:59:52 +00:00
FROM Traps IMPORT Message;
1987-05-13 14:36:45 +00:00
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 *)
1987-06-26 15:59:52 +00:00
Message("deadlock");
1987-05-13 14:36:45 +00:00
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.