[9] | 1 | (*$R-*)
|
---|
| 2 | IMPLEMENTATION MODULE Processes [1];
|
---|
| 3 | (*
|
---|
| 4 | Module: Processes
|
---|
| 5 | From: "Programming in Modula-2", 3rd, corrected edition, by N. Wirth
|
---|
| 6 | Version: $Header: /cvsup/minix/src/lib/ack/libm2/Processes.mod,v 1.1 2005/10/10 15:27:46 beng Exp $
|
---|
| 7 | *)
|
---|
| 8 |
|
---|
| 9 | FROM SYSTEM IMPORT ADDRESS, TSIZE, NEWPROCESS, TRANSFER;
|
---|
| 10 | FROM Storage IMPORT Allocate;
|
---|
| 11 | FROM Traps IMPORT Message;
|
---|
| 12 |
|
---|
| 13 | TYPE SIGNAL = POINTER TO ProcessDescriptor;
|
---|
| 14 |
|
---|
| 15 | ProcessDescriptor =
|
---|
| 16 | RECORD next: SIGNAL; (* ring *)
|
---|
| 17 | queue: SIGNAL; (* queue of waiting processes *)
|
---|
| 18 | cor: ADDRESS;
|
---|
| 19 | ready: BOOLEAN;
|
---|
| 20 | END;
|
---|
| 21 |
|
---|
| 22 | VAR cp: SIGNAL; (* current process *)
|
---|
| 23 |
|
---|
| 24 | PROCEDURE StartProcess(P: PROC; n: CARDINAL);
|
---|
| 25 | VAR s0: SIGNAL;
|
---|
| 26 | wsp: ADDRESS;
|
---|
| 27 | BEGIN
|
---|
| 28 | s0 := cp;
|
---|
| 29 | Allocate(wsp, n);
|
---|
| 30 | Allocate(cp, TSIZE(ProcessDescriptor));
|
---|
| 31 | WITH cp^ DO
|
---|
| 32 | next := s0^.next;
|
---|
| 33 | s0^.next := cp;
|
---|
| 34 | ready := TRUE;
|
---|
| 35 | queue := NIL
|
---|
| 36 | END;
|
---|
| 37 | NEWPROCESS(P, wsp, n, cp^.cor);
|
---|
| 38 | TRANSFER(s0^.cor, cp^.cor);
|
---|
| 39 | END StartProcess;
|
---|
| 40 |
|
---|
| 41 | PROCEDURE SEND(VAR s: SIGNAL);
|
---|
| 42 | VAR s0: SIGNAL;
|
---|
| 43 | BEGIN
|
---|
| 44 | IF s # NIL THEN
|
---|
| 45 | s0 := cp;
|
---|
| 46 | cp := s;
|
---|
| 47 | WITH cp^ DO
|
---|
| 48 | s := queue;
|
---|
| 49 | ready := TRUE;
|
---|
| 50 | queue := NIL
|
---|
| 51 | END;
|
---|
| 52 | TRANSFER(s0^.cor, cp^.cor);
|
---|
| 53 | END
|
---|
| 54 | END SEND;
|
---|
| 55 |
|
---|
| 56 | PROCEDURE WAIT(VAR s: SIGNAL);
|
---|
| 57 | VAR s0, s1: SIGNAL;
|
---|
| 58 | BEGIN
|
---|
| 59 | (* insert cp in queue s *)
|
---|
| 60 | IF s = NIL THEN
|
---|
| 61 | s := cp
|
---|
| 62 | ELSE
|
---|
| 63 | s0 := s;
|
---|
| 64 | s1 := s0^.queue;
|
---|
| 65 | WHILE s1 # NIL DO
|
---|
| 66 | s0 := s1;
|
---|
| 67 | s1 := s0^.queue
|
---|
| 68 | END;
|
---|
| 69 | s0^.queue := cp
|
---|
| 70 | END;
|
---|
| 71 | s0 := cp;
|
---|
| 72 | REPEAT
|
---|
| 73 | cp := cp^.next
|
---|
| 74 | UNTIL cp^.ready;
|
---|
| 75 | IF cp = s0 THEN
|
---|
| 76 | (* deadlock *)
|
---|
| 77 | Message("deadlock");
|
---|
| 78 | HALT
|
---|
| 79 | END;
|
---|
| 80 | s0^.ready := FALSE;
|
---|
| 81 | TRANSFER(s0^.cor, cp^.cor)
|
---|
| 82 | END WAIT;
|
---|
| 83 |
|
---|
| 84 | PROCEDURE Awaited(s: SIGNAL): BOOLEAN;
|
---|
| 85 | BEGIN
|
---|
| 86 | RETURN s # NIL
|
---|
| 87 | END Awaited;
|
---|
| 88 |
|
---|
| 89 | PROCEDURE Init(VAR s: SIGNAL);
|
---|
| 90 | BEGIN
|
---|
| 91 | s := NIL
|
---|
| 92 | END Init;
|
---|
| 93 |
|
---|
| 94 | BEGIN
|
---|
| 95 | Allocate(cp, TSIZE(ProcessDescriptor));
|
---|
| 96 | WITH cp^ DO
|
---|
| 97 | next := cp;
|
---|
| 98 | ready := TRUE;
|
---|
| 99 | queue := NIL
|
---|
| 100 | END
|
---|
| 101 | END Processes.
|
---|