]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/gm2-libs-iso/Semaphores.mod
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / gm2-libs-iso / Semaphores.mod
CommitLineData
1eee94d3
GM
1(* Semaphores.mod implement the ISO Semaphores specification.
2
83ffe9cd 3Copyright (C) 2010-2023 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. *)
26
27IMPLEMENTATION MODULE Semaphores ;
28
29(* Provides mutual exclusion facilities for use by processes. *)
30
31FROM Storage IMPORT ALLOCATE ;
32FROM Processes IMPORT ProcessId, Me, SuspendMe, Activate, UrgencyOf ;
33
34
35TYPE
36 SEMAPHORE = POINTER TO RECORD
37 value: CARDINAL ;
38 next : SEMAPHORE ;
39 head : ProcessList ;
40 END ;
41
42 ProcessList = POINTER TO RECORD
43 waiting: ProcessId ;
44 right,
45 left : ProcessList ;
46 END ;
47
48VAR
49 freeSem : SEMAPHORE ;
50 freeProcessList: ProcessList ;
51
52
53(*
54 Create - creates and returns s as the identity of a new
55 semaphore that has its associated count initialized
56 to initialCount, and has no processes yet waiting on it.
57*)
58
59PROCEDURE Create (VAR s: SEMAPHORE; initialCount: CARDINAL) ;
60BEGIN
61 s := newSemaphore () ;
62 WITH s^ DO
63 value := initialCount ;
64 next := NIL ;
65 head := NIL
66 END
67END Create ;
68
69
70(*
71 Destroy - recovers the resources used to implement the semaphore s,
72 provided that no process is waiting for s to become free.
73*)
74
75PROCEDURE Destroy (VAR s: SEMAPHORE) ;
76BEGIN
77 WITH s^ DO
78 IF head=NIL
79 THEN
80 next := freeSem ;
81 freeSem := s
82 ELSE
83 (* raise exception? *)
84 END
85 END
86END Destroy ;
87
88
89(*
90 newSemaphore -
91*)
92
93PROCEDURE newSemaphore () : SEMAPHORE ;
94VAR
95 s: SEMAPHORE ;
96BEGIN
97 IF freeSem=NIL
98 THEN
99 NEW (s)
100 ELSE
101 s := freeSem ;
102 freeSem := freeSem^.next
103 END ;
104 RETURN s
105END newSemaphore ;
106
107
108(*
109 newProcessList - returns a new ProcessList.
110*)
111
112PROCEDURE newProcessList () : ProcessList ;
113VAR
114 l: ProcessList ;
115BEGIN
116 IF freeProcessList=NIL
117 THEN
118 NEW (l)
119 ELSE
120 l := freeProcessList ;
121 freeProcessList := freeProcessList^.right
122 END ;
123 RETURN l
124END newProcessList ;
125
126
127(*
128 add - adds process, p, to queue, head.
129*)
130
131PROCEDURE add (VAR head: ProcessList; p: ProcessList) ;
132BEGIN
133 IF head=NIL
134 THEN
135 head := p ;
136 p^.left := p ;
137 p^.right := p
138 ELSE
139 p^.right := head ;
140 p^.left := head^.left ;
141 head^.left^.right := p ;
142 head^.left := p
143 END
144END add ;
145
146
147(*
148 sub - subtracts process, p, from queue, head.
149*)
150
151PROCEDURE sub (VAR head: ProcessList; p: ProcessList) ;
152BEGIN
153 IF (p^.left=head) AND (p=head)
154 THEN
155 head := NIL
156 ELSE
157 IF head=p
158 THEN
159 head := head^.right
160 END ;
161 p^.left^.right := p^.right ;
162 p^.right^.left := p^.left
163 END
164END sub ;
165
166
167(*
168 addProcess - adds the current process to the semaphore list.
169 Remove the current process from the ready queue.
170*)
171
172PROCEDURE addProcess (VAR head: ProcessList) ;
173VAR
174 l: ProcessList ;
175BEGIN
176 l := newProcessList() ;
177 WITH l^ DO
178 waiting := Me () ;
179 right := NIL ;
180 left := NIL
181 END ;
182 add (head, l) ;
183 SuspendMe
184END addProcess ;
185
186
187(*
188 chooseProcess -
189*)
190
191PROCEDURE chooseProcess (head: ProcessList) : ProcessList ;
192VAR
193 best, l: ProcessList ;
194BEGIN
195 best := head ;
196 l := head^.right ;
197 WHILE l#head DO
198 IF UrgencyOf (l^.waiting) > UrgencyOf (best^.waiting)
199 THEN
200 best := l
201 END ;
202 l := l^.right
203 END ;
204 RETURN best
205END chooseProcess ;
206
207
208(*
209 removeProcess - removes process, l, from the list and adds it to the
210 ready queue.
211*)
212
213PROCEDURE removeProcess (VAR head: ProcessList; l: ProcessList) ;
214BEGIN
215 sub (head, l) ;
216 WITH l^ DO
217 right := freeProcessList ;
218 freeProcessList := l ;
219 Activate (waiting)
220 END
221END removeProcess ;
222
223
224(*
225 Claim - if the count associated with the semaphore s is non-zero,
226 decrements this count and allows the calling process to
227 continue; otherwise suspends the calling process until
228 s is released.
229*)
230
231PROCEDURE Claim (s: SEMAPHORE) ;
232BEGIN
233 WITH s^ DO
234 IF value>0
235 THEN
236 DEC (value)
237 ELSE
238 addProcess (head)
239 END
240 END
241END Claim ;
242
243
244(*
245 Release - if there are any processes waiting on the semaphore s,
246 allows one of them to enter the ready state; otherwise
247 increments the count associated with s.
248*)
249
250PROCEDURE Release (s: SEMAPHORE) ;
251BEGIN
252 WITH s^ DO
253 IF head=NIL
254 THEN
255 INC (value)
256 ELSE
257 removeProcess (head, chooseProcess (head))
258 END
259 END
260END Release ;
261
262
263(*
264 CondClaim - returns FALSE if the call Claim(s) would cause the calling
265 process to be suspended; in this case the count associated
266 with s is not changed. Otherwise returns TRUE and the
267 associated count is decremented.
268*)
269
270PROCEDURE CondClaim (s: SEMAPHORE) : BOOLEAN ;
271BEGIN
272 WITH s^ DO
273 IF value>0
274 THEN
275 DEC (value) ;
276 RETURN TRUE
277 ELSE
278 RETURN FALSE
279 END
280 END
281END CondClaim ;
282
283
284BEGIN
285 freeSem := NIL ;
286 freeProcessList := NIL
287END Semaphores.