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