1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
PACKET spool manager DEFINES (* Autor: J. Liedtke *)
spool manager, server channel: (* 21.05.84 *)
LET que size = 100 ,
ack = 0 ,
nak = 1 ,
error nak = 2 ,
second phase ack = 5 ,
fetch code = 11 ,
save code = 12 ,
erase code = 14 ,
list code = 15 ,
all code = 17 ,
continue code = 100,
empty = 0 ,
used = 1 ;
TASK VAR order task , waiting server , from task , server ;
INT VAR order code , reply , first , last , list index ;
DATASPACE VAR ds ;
TEXT VAR from title ;
BOUND STRUCT (TEXT name, write pass, read pass) VAR msg ;
BOUND TEXT VAR error msg ;
BOUND STRUCT (TEXT tname, tpass, TASK task) VAR sv msg ;
FILE VAR list file ;
TEXT VAR entry name, entry task;
INT VAR command index , params ;
TEXT VAR command line, param 1, param 2 ;
LET spool command list =
"break:1.0start:2.01stop:4.0first:5.0killer:6.0 " ;
LET ENTRY = STRUCT (TEXT title, TASK origin, DATASPACE space, INT status) ;
ROW que size ENTRY VAR que ;
INT VAR server chan := 0;
PROC server channel (INT CONST ch):
server chan := ch
END PROC server channel;
INT PROC server channel:
server chan
END PROC server channel;
PROC spool manager (PROC server start) :
INT VAR old heap size := heap size;
begin (PROC server start, server) ;
set autonom ;
break ;
disable stop ;
first := 1 ;
last := 1 ;
from task := niltask ;
waiting server := niltask ;
spool ;
clear error ;
forget all dataspaces.
forget all dataspaces :
INT VAR i ;
FOR i FROM 1 UPTO que size REP
forget (que (i).space)
PER .
spool:
REP
wait (ds, order code, order task) ;
IF order code = fetch code THEN out of que
ELIF order code = save code THEN prepare into que
ELIF order code = second phase ack THEN into que
ELIF order code = erase code THEN delete que entry
ELIF order code = list code THEN list spool
ELIF order code = all code THEN y all
ELIF order code >= continue code
AND order task = supervisor THEN spool command (PROC server start)
FI;
clear error
PER;
collect heap garbage if necessary.
collect heap garbage if necessary:
IF heap size > old heap size + 2
THEN collect heap garbage;
old heap size := heap size
FI.
ENDPROC spool manager ;
PROC out of que :
forget (ds) ;
IF NOT (order task < myself)
THEN error ("not parent")
ELIF que empty
THEN waiting server := order task
ELSE send (order task, ack, que (first).space) ;
inc first
FI .
que empty : first = last .
ENDPROC out of que ;
PROC inc first :
que (first).status := empty ;
REP
first := first MOD que size + 1 ;
UNTIL first = last OR que (first).status <> empty PER
ENDPROC inc first ;
PROC dec first :
first DECR 1 ;
IF first = 0
THEN first := que size
FI
ENDPROC dec first ;
PROC prepare into que :
msg := ds ;
from task := order task ;
from title := CONCR (msg).name ;
send (order task, second phase ack, ds) .
ENDPROC prepare into que ;
PROC into que :
IF order task = from task
THEN try entry into spool
ELSE send (order task, nak, ds)
FI .
try entry into spool :
IF que full
THEN error ("spool overflow")
ELSE entry (que (last)) ;
last := next (last) ;
send (order task, ack, ds) ;
awake server if necessary
FI .
awake server if necessary :
IF NOT is niltask (waiting server)
THEN send (waiting server, ack, que (first).space , reply) ;
IF reply = ack
THEN waiting server := niltask ;
inc first
FI
FI .
que full : first = next (last) .
ENDPROC into que ;
PROC entry (ENTRY VAR que entry) :
que entry.title := from title ;
que entry.origin := from task ;
que entry.space := ds ;
que entry.status := used ;
ENDPROC entry ;
INT PROC next (INT CONST index) :
index MOD que size + 1
ENDPROC next ;
PROC delete que entry :
msg := ds ;
INT VAR index := first ;
WHILE index <> last REP
IF entry found
THEN erase entry (index) ;
send (order task, ack, ds) ;
LEAVE delete que entry
FI ;
index := next (index)
PER ;
error ("your file does not exist") .
entry found :
entry.status = used CAND entry.origin = order task
CAND entry.title = CONCR (msg).name .
entry : que (index) .
ENDPROC delete que entry ;
PROC erase entry (INT CONST index) :
entry.status := empty ;
forget (entry.space) ;
IF index = first
THEN inc first
FI .
entry : que (index) .
ENDPROC erase entry ;
PROC list spool :
forget (ds) ;
ds := nilspace ;
list file := sequential file (output, ds) ;
to first que entry ;
get next que entry (entry name, entry task) ;
WHILE entry name <> "" REP
putline (list file, text (entry task, 15) + " : " + entry name);
get next que entry (entry name, entry task)
PER;
send (order task, ack, ds) .
ENDPROC list spool ;
BOUND THESAURUS VAR all thesaurus;
PROC y all:
forget (ds);
ds := nilspace;
all thesaurus := ds;
all thesaurus := empty thesaurus;
to first que entry;
get next que entry (entry name, entry task); (* hier erster Eintrag *)
WHILE entryname <> "" REP
IF entry task = name (order task)
AND NOT (all thesaurus CONTAINS entry name)
THEN insert (all thesaurus, entry name)
FI;
get next que entry (entry name, entry task)
PER;
send (order task, ack, ds)
END PROC y all;
PROC to first que entry :
list index := first - 1
ENDPROC to first que entry ;
PROC get next que entry (TEXT VAR entry name, origin task name):
WHILE list index <> last REP
list index := next (list index)
UNTIL que (list index).status <> empty PER ;
IF que (list index).status = used
THEN origin task name := name (que (list index).origin) ;
entry name := que (list index).title
ELSE entry name := "";
origin task name := ""
FI .
ENDPROC get next que entry ;
PROC error (TEXT CONST error text) :
forget (ds) ;
ds := nilspace ;
error msg := ds ;
CONCR (error msg) := error text ;
send (order task, error nak, ds)
ENDPROC error ;
PROC spool command (PROC server start) :
enable stop ;
continue (order code - continue code) ;
command dialogue (TRUE) ;
disable stop ;
REP
get command ("gib spoolkommando :", command line);
analyze command (spool command list, command line, 3,
command index, params, param1, param2);
execute command
PER .
execute command :
SELECT command index OF
CASE 1 : break cmd
CASE 2 : start cmd
CASE 3 : start channel cmd
CASE 4 : stop cmd
CASE 5 : first cmd
CASE 6 : killer cmd
OTHERWISE do (command line) END SELECT .
start channel cmd:
server channel (int (param1));
start cmd;
break cmd.
break cmd:
break; set autonom ; LEAVE spool command.
start cmd :
IF is niltask (server)
THEN begin (PROC server start, server)
FI .
stop cmd :
IF NOT is niltask (server)
THEN command dialogue (FALSE) ;
end (server) ;
server := niltask
FI .
first cmd :
line ;
to first que entry ;
get next que entry (entry name, entry task);
IF entry name = ""
THEN LEAVE first cmd
FI ;
REP
get next que entry (entry name, entry task) ;
IF entry name = ""
THEN LEAVE first cmd
FI;
say (text (entry task, 15) + " : " + entry name) ;
IF yes (" als erstes")
THEN make to first entry ;
LEAVE first cmd
FI
PER .
make to first entry :
IF first = next (last)
THEN errorstop ("spool overflow")
ELSE dec first ;
que (first) := que (list index) ;
erase entry (list index)
FI .
killer cmd :
line ;
to first que entry ;
REP
get next que entry (entry name, entry task) ;
IF entry name = ""
THEN LEAVE killer cmd
FI ;
say (text (entry task, 15) + " : " + entry name) ;
IF yes (" loeschen")
THEN erase entry (list index)
FI
PER .
ENDPROC spool command ;
ENDPACKET spool manager ;
|