system/std.zusatz/1.7.3/src/scheduler

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
PACKET std schedule strategy DEFINES                (* Autor: J.Liedtke *)
                                                    (* Stand: 15.10.82  *)
    strategic decision :


PROC strategic decision 
              (INT CONST foreground workers, background workers,
               REAL CONST fore cpu load, back cpu load, paging load,
               INT VAR lowest activation prio, max background tasks) :
 
  IF no background permitted
    THEN lowest activation prio := 0 ;
         max background tasks := 0
    ELSE lowest activation prio := 10 ;
         select max background tasks
  FI .
 
no background permitted :
      foreground workers > 0 AND fore cpu load > 0.03 .

select max background tasks :
  IF fore cpu load > 0.01
    THEN max background tasks := 1
  ELIF paging load < 0.07
    THEN max background tasks := 3
  ELIF paging load < 0.15
    THEN max background tasks := 2
    ELSE max background tasks := 1
  FI .

ENDPROC strategic decision ;

ENDPACKET std schedule strategy ;


                                              (* Autor: J.Liedtke*)
PACKET eumelmeter DEFINES                     (* Stand: 11.10.83 *)
 
     init log ,
     log :
 
 
LET snapshot interval = 590.0 ;

REAL VAR next snapshot time ,
         time        , timex ,
         paging wait , paging wait x ,
         paging busy , paging busy x ,
         fore cpu    , fore cpu x ,
         back cpu    , back cpu x ,
         system cpu  , system cpu x ,
         delta t ;
INT VAR storage max, used ;
TEXT VAR record ;

PROC init log :

  time        := clock (1) ;
  paging wait := clock (2) ;
  paging busy := clock (3) ;
  fore cpu    := clock (4) ;
  back cpu    := clock (5) ;
  system cpu  := clock (6) ;
  next snapshot time := time + snapshot interval

ENDPROC init log ;

PROC log (INT CONST active terminals, active background) :

  new snapshot time if was clock reset ;
  IF clock (1) >= next snapshot time
    THEN save values ;
         get new values ;
         create stat record ;
         put log (record) ;
         define next snapshot time
  FI .

new snapshot time if was clock reset :
  IF clock (1) < next snapshot time - snapshot interval 
    THEN next snapshot time := clock (1)
  FI .

save values :
  time x := time ;
  paging wait x := paging wait ;
  paging busy x := paging busy ;
  fore cpu x    := fore cpu ;
  back cpu x    := back cpu ;
  system cpu x  := system cpu .

get new values :
  time := clock (1) ;
  paging wait := clock (2) ;
  paging busy := clock (3) ;
  fore cpu    := clock (4) ;
  back cpu    := clock (5) ;
  system cpu  := clock (6) ;
  storage (storage max, used) .

create stat record :
  record :=  text (used, 5) ;
  record CAT text (active terminals,3) ;
  record CAT text (active background,3) ;
  delta t := (time - time x) ;
  percent (paging wait, paging wait x) ;
  percent (paging busy, paging busy x) ;
  percent (fore cpu, fore cpu x) ;
  percent (back cpu, back cpu x) ;
  percent (system cpu, system cpu x) ;
  percent (last, 0.0) ;
  percent (nutz, 0.0) .

last :   paging wait  + paging busy  + fore cpu  + back cpu  + system cpu
       - paging waitx - paging busyx - fore cpux - back cpux - system cpux .

nutz :   time  - paging wait  - system cpu
       - timex + paging waitx + system cpux .

define next snapshot time :
  next snapshot time := time + snapshot interval .
 
ENDPROC log ;

PROC percent (REAL CONST neu, alt ) :

  record CAT text ( (neu-alt) / delta t * 100.0, 6,1) + "%"

ENDPROC percent ;

ENDPACKET eumelmeter ;



PACKET background que manager DEFINES                (* Autor: J.Liedtke *)
                                                     (* Stand: 15.10.82  *)
    into background que ,
    delete from background que ,
    get first from background que ,
    get next from background que :

LET que size = 100 ,
    ENTRY    = STRUCT (TASK task, INT class) ;

INT VAR end of que := 0 ,
        actual entry pos ;

ROW que size ENTRY VAR que ;


PROC into background que (TASK CONST task) :

  INT VAR class := prio (task) ;
  IF end of que = que size
    THEN delete all not existing tasks
  FI ;
  check whether already in que ;
  IF already in que
    THEN IF in same class
           THEN LEAVE into background que
           ELSE delete from background que (task) ;
                into background que (task)
         FI
    ELSE insert new entry
  FI .

check whether already in que :
  INT VAR entry pos := 1 ;
  WHILE entry pos <= end of que  REP
    IF que (entry pos).task = task
      THEN LEAVE check whether already in que
    FI ;
    entry pos INCR 1
  PER .

already in que :  entry pos <= end of que .

in same class :   que (entry pos).class = class .

insert new entry :
  end of que INCR 1 ;
  que (end of que) := ENTRY:( task, class ) .

delete all not existing tasks :
  INT VAR j ;
  FOR j FROM 1 UPTO end of que REP
    TASK VAR examined := que (j).task ;
    IF NOT exists (examined)
      THEN delete from background que (examined)
    FI
  PER .

ENDPROC into background que ;

PROC delete from background que (TASK CONST task) :

  search for entry ;
  IF entry found
    THEN delete entry ;
         update actual entry pos 
  FI .

search for entry :
  INT VAR entry pos := 1 ;
  WHILE entry pos <= end of que REP
    IF que (entry pos).task = task
      THEN LEAVE search for entry
    FI ;
    entry pos INCR 1
  PER .

entry found : entry pos <= end of que .

delete entry :
  INT VAR i ;
  FOR i FROM entry pos UPTO end of que - 1 REP
    que (i) := que (i+1)
  PER ;
  end of que DECR 1 .

update actual entry pos :
  IF actual entry or following one deleted
    THEN actual entry pos DECR 1
  FI .

actual entry or following one deleted :
  entry pos >= actual entry pos .

ENDPROC delete from background que ;

PROC get first from background que (TASK VAR task, INT CONST lowest class) :

  actual entry pos := 0 ;
  get next from background que (task, lowest class)

ENDPROC get first from background que ;

PROC get next from background que (TASK VAR task, INT CONST lowest class) :
 
  search next entry of permitted class ;
  IF actual entry pos <= end of que
    THEN task := que (actual entry pos).task
    ELSE task := niltask
  FI .

search next entry of permitted class :
  REP
    actual entry pos INCR 1
  UNTIL actual entry pos > end of que 
        COR que (actual entry pos).class <= lowest class PER.

ENDPROC get next from background que ;

ENDPACKET background que manager ;

 

PACKET scheduler DEFINES                         (* Autor: J.Liedtke *)
                                                 (* Stand: 09.12.82  *)
    scheduler :
 

LET std background prio     = 7 ,
    highest background prio = 5 ,
    long slice              = 6000 ,
    short slice             = 600 ,
    blocked busy            = 4 ;

INT VAR slice ,
        foreground workers ,
        background workers ;

BOOL VAR is logging ;

REAL VAR fore cpu load , back cpu load , paging load ;


access catalogue ;
TASK CONST ur task := brother (supervisor) ;

TASK VAR actual task ;


PROC scheduler :
  IF yes ("mit eumelmeter")
    THEN is logging := TRUE
    ELSE is logging := FALSE
  FI ;
  task password ("-") ;
  break ;
  set autonom ;
  command dialogue (FALSE) ;
  forget ("scheduler", quiet) ;
  disable stop; 
  REP scheduler operation; 
      clear error 
  PER; 
 
END PROC scheduler; 
 
PROC scheduler operation:
  enable stop;
  IF is logging 
    THEN init log 
  FI;
  slice := short slice ;
  init system load moniting ;
  REP
    pause (slice) ;
    monit system load ;
    look at all active user tasks and block background workers ;
    activate next background workers if possible ;
    IF is logging
      THEN log (foreground workers, background workers)
    FI
  PER .

init system load moniting :
  REAL VAR 
  time     x := clock (1) ,
  fore cpu x := clock (4) ,
  back cpu x := clock (5) ,
  paging   x := clock (2) + clock (3) .

monit system load :
  REAL VAR interval := clock (1) - time x ;
  fore cpu load := (clock (4) - fore cpu x) / interval ;
  back cpu load := (clock (5) - back cpu x) / interval ;
  paging load   := (clock (2) + clock (3) - paging x) / interval ;
  time     x := clock (1) ;
  fore cpu x := clock (4) ;
  back cpu x := clock (5) ;
  paging   x := clock (2) + clock (3) .

ENDPROC scheduler operation;

PROC look at all active user tasks and block background workers :

  foreground workers := 0 ;
  background workers := 0 ;
  actual task := myself ;
  next active (actual task) ;
  WHILE NOT (actual task = myself) REP
    IF actual task < ur task
      THEN look at this task
    FI ;
    next active (actual task)
  END REP .

look at this task :
  IF channel (actual task) >= 0
    THEN foreground workers INCR 1
    ELSE background workers INCR 1 ;
         block actual task if simple worker
  FI .

block actual task if simple worker :
  IF son (actual task) = niltask
    THEN pause (5) ;
         block (actual task) ;
         IF status (actual task) = blocked busy
           THEN set background prio ;
                into background que (actual task)
         ELIF prio (actual task) < highest background prio
           THEN unblock (actual task)
         FI
  FI .

set background prio :
  IF prio (actual task) < highest background prio
    THEN prio (actual task, std background prio)
  FI .
 
ENDPROC look at all active user tasks and block background workers ;

PROC activate next background workers if possible :

  INT VAR lowest activation prio ,
          max background workers ,
          active background workers := 0 ;

  strategic decision (foreground workers, background workers,
                      fore cpu load, back cpu load, paging load,
                      lowest activation prio, max background workers) ;

  IF background permitted
    THEN try to activate background workers
  FI ;
  IF active background workers > 0
    THEN slice := short slice
    ELSE slice := long slice
  FI .

background permitted : max background workers > 0 .

try to activate background workers :
  get first from background que (actual task, lowest activation prio) ;
  IF NOT is niltask (actual task)
    THEN delete from background que (actual task)
  FI ;

  WHILE active background workers < max background workers REP
    IF is niltask (actual task)
      THEN LEAVE try to activate background workers
    ELIF status (actual task) <> blocked busy
      THEN delete from background que (actual task)
    ELSE
           unblock (actual task) ;
           active background workers INCR 1
    FI ;
    get next from background que (actual task, lowest activation prio)
  PER .

ENDPROC activate next background workers if possible ;
 
ENDPACKET scheduler ;
 
scheduler;