source: trunk/minix/lib/ack/libm2/Semaphores.mod@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 2.3 KB
Line 
1(*
2 (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 See the copyright notice in the ACK home directory, in the file "Copyright".
4*)
5
6(*$R-*)
7IMPLEMENTATION MODULE Semaphores [1];
8(*
9 Module: Processes with semaphores
10 Author: Ceriel J.H. Jacobs
11 Version: $Header: /cvsup/minix/src/lib/ack/libm2/Semaphores.mod,v 1.1 2005/10/10 15:27:46 beng Exp $
12
13 Quasi-concurrency implementation
14*)
15
16 FROM SYSTEM IMPORT ADDRESS, NEWPROCESS, TRANSFER;
17 FROM Storage IMPORT Allocate;
18 FROM random IMPORT Uniform;
19 FROM Traps IMPORT Message;
20
21 TYPE Sema = POINTER TO Semaphore;
22 Processes = POINTER TO Process;
23 Semaphore =
24 RECORD
25 level: CARDINAL;
26 END;
27 Process =
28 RECORD next: Processes;
29 proc: ADDRESS;
30 waiting: Sema;
31 END;
32
33 VAR cp: Processes; (* current process *)
34
35 PROCEDURE StartProcess(P: PROC; n: CARDINAL);
36 VAR s0: Processes;
37 wsp: ADDRESS;
38 BEGIN
39 s0 := cp;
40 Allocate(wsp, n);
41 Allocate(cp, SIZE(Process));
42 WITH cp^ DO
43 next := s0^.next;
44 s0^.next := cp;
45 waiting := NIL;
46 END;
47 NEWPROCESS(P, wsp, n, cp^.proc);
48 TRANSFER(s0^.proc, cp^.proc);
49 END StartProcess;
50
51 PROCEDURE Up(VAR s: Sema);
52 BEGIN
53 s^.level := s^.level + 1;
54 ReSchedule;
55 END Up;
56
57 PROCEDURE Down(VAR s: Sema);
58 BEGIN
59 IF s^.level = 0 THEN
60 cp^.waiting := s;
61 ELSE
62 s^.level := s^.level - 1;
63 END;
64 ReSchedule;
65 END Down;
66
67 PROCEDURE NewSema(n: CARDINAL): Sema;
68 VAR s: Sema;
69 BEGIN
70 Allocate(s, SIZE(Semaphore));
71 s^.level := n;
72 RETURN s;
73 END NewSema;
74
75 PROCEDURE Level(s: Sema): CARDINAL;
76 BEGIN
77 RETURN s^.level;
78 END Level;
79
80 PROCEDURE ReSchedule;
81 VAR s0: Processes;
82 i, j: CARDINAL;
83 BEGIN
84 s0 := cp;
85 i := Uniform(1, 5);
86 j := i;
87 LOOP
88 cp := cp^.next;
89 IF Runnable(cp) THEN
90 DEC(i);
91 IF i = 0 THEN EXIT END;
92 END;
93 IF (cp = s0) AND (j = i) THEN
94 (* deadlock *)
95 Message("deadlock");
96 HALT
97 END;
98 END;
99 IF cp # s0 THEN TRANSFER(s0^.proc, cp^.proc); END;
100 END ReSchedule;
101
102 PROCEDURE Runnable(p: Processes): BOOLEAN;
103 BEGIN
104 IF p^.waiting = NIL THEN RETURN TRUE; END;
105 IF p^.waiting^.level > 0 THEN
106 p^.waiting^.level := p^.waiting^.level - 1;
107 p^.waiting := NIL;
108 RETURN TRUE;
109 END;
110 RETURN FALSE;
111 END Runnable;
112BEGIN
113 Allocate(cp, SIZE(Process));
114 WITH cp^ DO
115 next := cp;
116 waiting := NIL;
117 END
118END Semaphores.
Note: See TracBrowser for help on using the repository browser.