123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- (*$R-*)
- IMPLEMENTATION MODULE Processes [1];
- (*
- Module: Processes
- From: "Programming in Modula-2", 3rd, corrected edition, by N. Wirth
- Version: $Id$
- *)
- FROM SYSTEM IMPORT ADDRESS, TSIZE, NEWPROCESS, TRANSFER;
- FROM Storage IMPORT Allocate;
- FROM Traps IMPORT Message;
- 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 *)
- Message("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.
|