system/multiuser/1.7.5/src/tasks

Raw file
Back to index

  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
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
(* ------------------- VERSION 9 vom 09.06.86 ------------------- *)
PACKET tasks DEFINES                          (* Autor: J.Liedtke *)
 
    TASK ,
    PROCA ,
    := ,
    = ,
    < ,
    / ,
    niltask ,
    is niltask ,
    exists ,
    exists task ,
    supervisor ,
    myself ,
    public ,
    proca ,
    collector ,
    access ,
    name ,
    task ,
    canal ,
    dataspaces ,
    index ,
    station ,
    update ,
    father ,
    son ,
    brother ,
    next active ,
    access catalogue ,
    family password ,
    task in catalogue ,
    entry ,
    delete ,
    define station ,

    pcb ,
    status ,
    channel ,
    clock ,
    storage ,
    callee ,

    send ,
    wait ,
    call ,
    pingpong ,
    collected destination ,
 
    begin ,
    end ,
    break ,
    continue ,
    rename myself ,
    task password ,
    set autonom ,
    reset autonom ,
    set automatic startup ,
    reset automatic startup ,

    sys cat :

 

LET nil = 0 ,

    max version = 30000 ,
    max task = 125 ,
    max station no = 127 ,
    sv no = 1 ,

    hex ff   = 255 ,
    hex 7f00 = 32512 ,

    collected dest field 1 = 2 ,
    collected dest field 2 = 3 ,
    channel field = 4 ,
    myself no field = 9 ,
    myself version field = 10 ,
    callee no field = 11 ,
    callee version field = 12 ,

    highest terminal channel = 16 ,
    number of channels       = 32 ,

    wait state = 2 ,

    ack                            = 0 ,
    nak                            = 1 ,
    error nak                      = 2 ,
    system catalogue code          = 3 ,
    begin code                     = 4 ,
    end code                       = 5 ,
    break code                     = 6 ,
    rename code                    = 7 ,
    password code                  = 9 ,
    family password code           = 40 ,
    set autonom code               = 41 ,
    reset autonom code             = 42 ,
    task of channel code           = 45 ,
    canal of channel code          = 46 ,
    set automatic startup code     = 47 ,
    reset automatic startup code   = 48 ,

    continue code                  = 100,
    define station code            = 32000,

    lowest ds number               = 4 ,
    highest ds number              = 255 ;


TYPE TASK  = STRUCT (INT no, version) ,
     PROCA = STRUCT (INT a, b) ;
 
OP := (PROCA VAR right, PROCA CONST left) :
  CONCR (right) := CONCR (left)
ENDOP :=  ;

PROCA PROC proca (PROC p) : 

  push (0, PROC p) ;
  pop

ENDPROC proca ;

PROC push (INT CONST dummy, PROC p) : ENDPROC push ;

PROCA PROC pop :
  PROCA VAR res;
  res
ENDPROC pop ;

TASK CONST niltask := TASK: (0,0) ,
           collector  := TASK: (-1,0) ;

TASK PROC supervisor :
 
  TASK: (my station id + sv no, 0) .

my station id :  pcb (myself no field) AND hex 7f00 .

ENDPROC supervisor ;

TASK VAR   father task ;

INITFLAG VAR catalogue known := FALSE , father known := FALSE ;



LET TASKVECTOR = STRUCT (INT version, father, son, brother) ;


DATASPACE VAR catalogue space , sv space ;

BOUND STRUCT (THESAURUS dir,
              ROW max task TASKVECTOR link) VAR system catalogue ;
 initialize catalogue ; 
 
BOUND STRUCT (TEXT tname, tpass, TASK task, PROCA start proc) VAR sv msg ;


PROC initialize catalogue :

  catalogue space := nilspace ;
  system catalogue := catalogue space ;
  system catalogue.dir := empty thesaurus ;

  insert (system catalogue.dir, "SUPERVISOR") ;
  insert (system catalogue.dir, "UR") ;
  system catalogue.link (1) := TASKVECTOR:(0,0,0,2) ;
  system catalogue.link (2) := TASKVECTOR:(0,0,0,0) .

ENDPROC initialize catalogue ;

DATASPACE PROC sys cat :
  catalogue space
ENDPROC sys cat ;


TASK PROC myself :

  TASK: (pcb (myself no field), pcb (myself version field))

ENDPROC myself ;


OP := (TASK VAR dest, TASK CONST source):

  CONCR (dest) := CONCR (source)

ENDOP := ;

BOOL OP = (TASK CONST left, right) :

  left.no = right.no  AND  left.version = right.version

ENDOP = ;

BOOL PROC is niltask (TASK CONST t) :

  t.no = 0

ENDPROC is niltask ;

BOOL OP < (TASK CONST left, right) :

  IF both of my station
    THEN access (left) ;
         access (right) ;
            ( index (left) > 0  CAND  index (left) <= max task )
         CAND
            ( father (left) = right  COR  father (left) < right )
    ELSE FALSE
  FI .

both of my station :
  station (left) = station (right) AND station (right) = station (myself) .

ENDOP < ;

BOOL PROC exists (TASK CONST task) :

  EXTERNAL 123

ENDPROC exists ;
 
BOOL PROC exists task (TEXT CONST name) :

  task id (name).no <> 0

ENDPROC exists task ;

TEXT PROC name (TASK CONST task) :

  IF is task of other station
  THEN external name (task)
  ELSE
    access (task) ;
    INT CONST task no := index (task) ;
    IF task in catalogue (task ,task no)
      THEN name (system catalogue.dir, task no) 
      ELSE ""
    FI 
  FI.

is task of other station :
  (task.no AND hex 7f00) <> (pcb (myself no field) AND hex 7f00) .
 
ENDPROC name ;

BOOL PROC task in catalogue (TASK CONST task, INT CONST task no) :

  access catalogue ;
  task no >= 1 CAND task no <= max task CAND
  task.version = system catalogue.link (task no).version .

ENDPROC task in catalogue ;

PROC access (TASK CONST task) :

  INT CONST task no := task.no AND hex ff ;
  IF task no < 1 OR task no > max task
    THEN
  ELIF is task of other station
    THEN errorstop ("TASK anderer Station")
  ELIF actual task id not in catalogue COR NOT exists (task)
    THEN access catalogue
  FI .

actual task id not in catalogue :
  NOT initialized (catalogue known)  COR
  ( task no > 0 CAND catalogue version <> task.version ) .
 
catalogue version :  system catalogue.link (task no).version .

is task of other station :
  (task.no AND hex 7f00) <> (pcb (myself no field) AND hex 7f00) .

ENDPROC access ;

TASK PROC task (TEXT CONST task name) :

  TASK CONST id := task id (task name) ;
  IF id.no = 0
    THEN errorstop (""""+task name+""" gibt es nicht")
  FI ;
  id

ENDPROC task ;

TASK PROC task id (TEXT CONST task name) :

  IF task name = "-" OR task name = ""
    THEN errorstop ("Taskname unzulaessig")
  FI ;
  IF NOT initialized (catalogue known)
    THEN access catalogue
  FI ;

  TASK VAR
  id := task id (link (system catalogue.dir, task name)) ;
  IF NOT exists (id)
    THEN access catalogue ;
         id  := task id (link (system catalogue.dir, task name)) ;
  FI ;
  id .

ENDPROC task id ;

TASK OP / (TEXT CONST task name) :

  task (task name)

ENDOP / ;

INT PROC index (TASK CONST task) :

  IF NOT initialized (catalogue known)
    THEN access catalogue
  FI ;
  task.no AND hex ff

ENDPROC index ;

INT PROC station (TASK CONST task) :

  task.no DIV 256

ENDPROC station ;

PROC update (TASK VAR task) :

  IF task.no <> nil
    THEN task.no := (task.no AND hex ff) + new station number
  FI .

new station number :  (pcb (myself no field) AND hex 7f00) .

ENDPROC update ;


TASK PROC public :

  task ("PUBLIC")

ENDPROC public ;

TASK PROC father :

  IF NOT initialized (father known) COR station or rename changed father id
    THEN access catalogue ;
         father task := father (myself)
  FI ;
  father task .

station or rename changed father id :
  NOT exists (father task) .

ENDPROC father ;

INT VAR task no ;

TASK PROC father (TASK CONST task) :

  task no := index (task) ;
  task id (system catalogue.link (task no).father) .

ENDPROC father ;

TASK PROC son (TASK CONST task) :

  task no := index (task) ;
  IF task no = nil
    THEN supervisor
    ELSE task id (system catalogue.link (task no).son)
  FI .

ENDPROC son ;

TASK PROC brother (TASK CONST task) :

  task no := index (task) ;
  task id (system catalogue.link (task no).brother) .

ENDPROC brother ;

PROC next active (TASK VAR task) :

  next active task index (task.no) ;
  IF task.no > 0
    THEN task.version := pcb (task, myself version field)
    ELSE task.version := 0
  FI 

ENDPROC next active ;

PROC next active task index (INT CONST no) :

  EXTERNAL 118

ENDPROC next active task index ;

TASK PROC task id (INT CONST task nr) :

  INT VAR task index := task nr AND hex ff ;
  TASK VAR result ;
  result.no := task index ;
  IF task index = nil
    THEN result.version := 0
    ELSE result.version := system catalogue.link (task index).version ;
         result.no INCR my station id
  FI ;
  result .

my station id : pcb (myself no field) AND hex 7f00 .

ENDPROC task id ;

PROC access catalogue :

  IF this is not supervisor
    THEN get catalogue from supervisor
  FI .

this is not supervisor :
  (pcb (myself no field) AND hex ff) <> sv no .

get catalogue from supervisor :
  INT VAR dummy reply ;
  forget (catalogue space) ;
  catalogue space := nilspace ;
  call (supervisor, system catalogue code, catalogue space, dummy reply) ;
  system catalogue := catalogue space .

ENDPROC access catalogue ;


PROC entry (TASK CONST father task, TEXT CONST task name,
            TASK VAR son task) :

  IF task name <> "-" CAND (system catalogue.dir CONTAINS task name)
    THEN errorstop (""""+task name+""" existiert bereits")
  ELIF is niltask (father task)
    THEN errorstop ("Vatertask existiert nicht")
  ELSE   entry task 
  FI .

entry task :
  INT VAR son task nr ;
  INT CONST father task nr := index (father task) ;
  insert (system catalogue.dir, task name, son task nr) ;
  IF son task nr = nil OR son task nr > max task
    THEN delete (system catalogue.dir, son task nr) ;
         son task := niltask ;
         errorstop ("zu viele Tasks")
    ELSE insert task (father task, father vec, son task, son vec, son tasknr)
  FI .

father vec : system catalogue.link (father task nr) .

son vec    : system catalogue.link (son task nr) .

ENDPROC entry ;

PROC insert task (TASK CONST father task, TASKVECTOR VAR father vec,
                  TASK VAR son task, TASKVECTOR VAR son vec, INT CONST nr) :

  initialize version number if son vec is first time used ; 
  increment version (son vec) ;
  son task.no := my station id + nr ;
  son task.version := son vec.version ;
  link into task tree .

initialize version number if son vec is first time used :
  IF son vec.version < 0
    THEN son vec.version := 0
  FI .

link into task tree :
  son vec.son := nil ;
  son vec.brother := father vec.son ;
  son vec.father := index (father task) ;
  father vec.son := son task.no .

my station id :  pcb (myself no field) AND hex 7f00 .

END PROC insert task ;


PROC delete (TASK CONST superfluous) :

  INT CONST superfluous nr := index (superfluous) ;
  delete (system catalogue.dir, superfluous nr) ;
  delete superfluous task ;
  increment version (superfluous vec) .
 
delete superfluous task :
  INT CONST successor of superfluous := superfluous vec.brother ;
  TASK VAR
  last := father (superfluous) ,
  actual := son (last) ;
  IF actual = superfluous
    THEN delete first son of last
    ELSE search previous brother of superfluous ;
         delete from brother chain
  FI .

delete first son of last :
  last vec.son := successor of superfluous .

search previous brother of superfluous :
  REP
    last := actual ;
    actual := brother (actual)
  UNTIL actual = superfluous PER .

delete from brother chain :
  last vec.brother := successor of superfluous .

last vec        :   system catalogue.link (index (last)) .

superfluous vec :   system catalogue.link (superfluous nr) .

ENDPROC delete ;


PROC name (TASK VAR task, TEXT CONST new name) :

  INT CONST task no := index (task) ;
  IF (system catalogue.dir CONTAINS new name) AND (new name <> "-")
                  AND (name (task) <> new name)
    THEN errorstop (""""+new name+""" existiert bereits")
    ELSE rename (system catalogue.dir, task no, new name) ;
         increment version (system catalogue.link (task no)) ;
         IF this is supervisor
           THEN update task version in pcb and task variable
         FI
  FI .

this is supervisor :  (pcb (myself no field) AND hex ff) = sv no .

update task version in pcb and task variable :
  INT CONST new version := system catalogue.link (task no).version ;
  write pcb (task, myself version field, new version) ;
  task.version := new version .

ENDPROC name ;


PROC increment version (TASKVECTOR VAR task vec) :

  task vec.version := task vec.version MOD max version + 1

ENDPROC increment version ;


INT PROC pcb (TASK CONST id, INT CONST field) :
 
  EXTERNAL 104

ENDPROC pcb ;

INT PROC status (TASK CONST id) :

  EXTERNAL 107

ENDPROC status ;

INT PROC channel (TASK CONST id) :

  pcb (id, channel field)

ENDPROC channel ;

REAL PROC clock (TASK CONST id) :

  EXTERNAL 106

ENDPROC clock ;

INT PROC storage (TASK CONST id) :

  INT VAR ds number, storage sum := 0, ds size;
  FOR ds number FROM lowest ds number UPTO highest ds number REP
    ds size := pages (ds number, id) ;
    IF ds size > 0
      THEN storage sum INCR ((ds size + 1) DIV 2)
    FI
  PER ;
  storage sum

ENDPROC storage ;

INT PROC pages (INT CONST ds number, TASK CONST id) :

  EXTERNAL 88

ENDPROC pages ;

TASK PROC callee (TASK CONST from) :

  IF status (from) = wait state
    THEN TASK:(pcb (from, callee no field), pcb (from, callee version field))
    ELSE niltask
  FI

ENDPROC callee ;


PROC send (TASK CONST dest, INT CONST send code, DATASPACE VAR ds,
           INT VAR quit) :
  EXTERNAL  113
 
ENDPROC send ;

PROC send (TASK CONST dest, INT CONST send code, DATASPACE VAR ds) :

  INT VAR dummy quit ;
  send (dest, send code, ds, dummy quit) ;
  forget (ds)

ENDPROC send ;

PROC wait (DATASPACE VAR ds, INT VAR receive code, TASK VAR source) :

  EXTERNAL 114
 
ENDPROC wait ;

PROC call (TASK CONST dest, INT CONST order code, DATASPACE VAR ds,
           INT VAR reply code) :
  EXTERNAL 115
 
ENDPROC call ;

PROC pingpong (TASK CONST dest, INT CONST order code, DATASPACE VAR ds,
                  INT VAR reply code) :
  EXTERNAL 122
 
ENDPROC pingpong ;

TASK PROC collected destination :

  TASK: (pcb (collected dest field 1), pcb (collected dest field 2))

ENDPROC collected destination ;


PROC begin (PROC start, TASK VAR new task) :

  begin ("-", PROC start, new task)

ENDPROC begin ;

PROC begin (TEXT CONST son name, PROC start, TASK VAR new task) :

  enable stop ;
  forget (sv space) ;
  sv space := nilspace ;
  sv msg := sv space ;
  CONCR (sv msg).tname := son name ;
  CONCR (sv msg).start proc := proca (PROC start) ;
  supervisor call (begin code) ;
  sv msg := sv space ;
  new task := CONCR (sv msg).task .
 
ENDPROC begin ;

PROC begin (DATASPACE VAR ds, PROC start, INT VAR reply) :

  sv msg := ds ;
  sv msg.start proc := proca (PROC start)  ;
  call (supervisor, begin code, ds, reply)

ENDPROC begin ;

PROC end :

  command dialogue (TRUE) ;
  say ("task """) ;
  say (name (myself)) ;
  IF yes (""" loeschen")
    THEN eumel must advertise ;
         end (myself)
  FI

ENDPROC end ;

PROC end (TASK CONST id) :

  forget (sv space) ;
  sv space := nilspace ;
  sv msg := sv space ;
  CONCR (sv msg).task := id ;
  supervisor call (end code)

ENDPROC end ;

PROC break (QUIET CONST quiet) :

  simple supervisor call (break code)

ENDPROC break ;

PROC break :

  eumel must advertise ;
  simple supervisor call (break code)

ENDPROC break ;

PROC continue (INT CONST channel nr) :
 
  simple supervisor call (continue code + channel nr)

ENDPROC continue ;

PROC rename myself (TEXT CONST new name) :

  forget (sv space) ;
  sv space := nilspace ;
  sv msg := sv space ;
  CONCR (sv msg).tname := new name ;
  supervisor call (rename code) .

ENDPROC rename myself ;


PROC simple supervisor call (INT CONST code) :

  forget (sv space) ;
  sv space := nilspace ;
  supervisor call (code)

ENDPROC simple supervisor call ;
 
PROC supervisor call (INT CONST code) :

  INT VAR answer ;
  call (supervisor, code, sv space, answer) ;
  WHILE answer = nak REP
    pause (20) ;
    call (supervisor, code, sv space, answer)
  PER ;
  IF answer = error nak
    THEN BOUND TEXT VAR error message := sv space ;
         errorstop (CONCR (error message))
  FI 

ENDPROC supervisor call ;

PROC task password (TEXT CONST password) :

  IF online 
    THEN say (""3""5""10"")
  FI ;
  forget (sv space) ;
  sv space := nilspace ;
  sv msg := sv space ;
  CONCR (sv msg).tpass := password ;
  supervisor call (password code) ;
  cover tracks .

ENDPROC task password ;

PROC set autonom :
 
  simple supervisor call (set autonom code)

ENDPROC set autonom ;

PROC reset autonom :

  simple supervisor call (reset autonom code)

ENDPROC reset autonom ;

PROC set automatic startup :
    simple supervisor call (set automatic startup code)
ENDPROC set automatic startup ;

PROC reset automatic startup :
    simple supervisor call (reset automatic startup code)
ENDPROC reset automatic startup ;

PROC define station (INT CONST station number) :

  IF this is supervisor
    THEN update all tasks
    ELIF i am privileged
        THEN IF station number is valid
               THEN send define station message
               ELSE errorstop ("ungueltige Stationsnummer (0 - 127)")
             FI
        ELSE errorstop ("falscher Auftrag fuer Task ""SUPERVISOR""")
  FI .

update all tasks :
  start at supervisor ;
  REP
    get next task ;
    IF no more task found
      THEN update station number of supervisor ;
           LEAVE update all tasks
    FI ;
    update station number of actual task
  PER .

i am privileged :
  myself < supervisor .

station number is valid :
  station number >= 0 AND station number <= max station no .

start at supervisor :
  TEXT VAR name ;
  INT VAR index := sv no .
 
get next task :
  get (system catalogue.dir, name, index) .
 
no more task found :  index = 0 .

update station number of actual task :
  write pcb (task id (index), myself no field, station number * 256 + index).

update station number of supervisor :
  write pcb (supervisor, myself no field, station number * 256 + sv no) .

send define station message :
  forget (sv space) ;
  sv space := nilspace ;
  INT VAR receipt ;
  REP
    send (supervisor, define station code+station number, sv space, receipt)
  UNTIL receipt = ack PER .

this is supervisor :
  (pcb (myself no field) AND hex ff) = sv no .

ENDPROC define station ;


TASK OP / (INT CONST station number, TEXT CONST task name) :

  IF station number = station (myself)
    THEN task (task name)
    ELSE get task id from other station
  FI .

get task id from other station :
  enable stop ;
  forget (sv space) ;
  sv space := nilspace ;
  BOUND TEXT VAR name message := sv space ;
  name message := task name ;
  INT VAR reply ;
  call (collector, station number, sv space, reply) ;
  IF reply = ack
    THEN BOUND TASK VAR result := sv space ;
         CONCR (result) 
  ELIF reply = error nak
    THEN name message := sv space;
         disable stop;
         errorstop (name message) ;
         forget (sv space) ;
         niltask
    ELSE forget (sv space);
         errorstop ("Collector-Task fehlt") ;
         niltask
  FI

ENDOP / ;


TASK OP / (INT CONST station number, TASK CONST tsk):

  station number / name (tsk)

END OP / ;

 
TEXT PROC external name (TASK CONST tsk):

  IF tsk = nil task 
  THEN 
    ""
  ELIF tsk = collector
  THEN
    "** collector **"
  ELSE
    name via net
  FI.

name via net:
  enable stop ;
  forget (sv space);
  sv space := nil space;
  BOUND TASK VAR task message := sv space;
  task message := tsk;
  INT VAR reply;
  call (collector, 256, sv space, reply);
  BOUND TEXT VAR result := sv space;
  CONCR (result).

END PROC external name;

PROC write pcb (TASK CONST task, INT CONST field, value) :
  EXTERNAL  105
ENDPROC write pcb ;

TASK PROC task (INT CONST channel number) :

  IF channel number < 1 OR channel number > 32
    THEN errorstop ("ungueltige Kanalnummer")
  FI ;
  forget (sv space) ;
  sv space := nilspace ;
  sv msg := sv space ;
  sv msg.tname := text (channel number) ;
  supervisor call (task of channel code) ;
  sv msg := sv space ;
  sv msg.task

END PROC task;

TASK PROC canal (INT CONST channel number) :

  IF channel number < 1 OR channel number > highest terminal channel
    THEN errorstop ("ungueltige Kanalnummer")
  FI ;
  forget (sv space);
  sv space := nilspace ;
  sv msg := sv space ;
  sv msg.tname := text (channel number) ;
  supervisor call (canal of channel code) ;
  sv msg := sv space ;
  sv msg.task

END PROC canal ;

PROC family password (TEXT CONST password) :

  IF online 
    THEN say (""3""5""10"")
  FI ;
  forget (sv space) ;
  sv space := nilspace ;
  sv msg := sv space ;
  sv msg.tpass := password ;
  supervisor call (family password code) ;
  cover tracks .

ENDPROC family password ;

INT PROC dataspaces (TASK CONST task) :

  INT VAR ds number, spaces := 0 ;
  FOR ds number FROM lowest ds number UPTO highest ds number REP
    IF pages (ds number, index (task)) >= 0
      THEN spaces INCR 1
    FI
  PER ;
  spaces

ENDPROC dataspaces ;

INT PROC dataspaces :
  dataspaces (myself)
ENDPROC dataspaces ;

INT PROC pages (INT CONST ds number, INT CONST task no) :
  EXTERNAL 88
ENDPROC pages ;

ENDPACKET tasks ;