|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 86016 (0x15000) Types: TextFile Names: »ttramos«
└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ. └─⟦b2ec5d50f⟧ └─⟦this⟧ »ttramos«
begin <* variables for claiming (accumulating) basic entities *> integer maxsem, maxsemch, maxop, maxcoru, maxmessext, maxprocext, maxnettoop; <* fields defining current position in pools af basic entities during initialization *> integer array field firstsem, firstsim, firstcoru, firstop, optop; <* variables used as pointers to 'current object' (work variables) *> integer messext, procext, timeinterval, testbuffering; integer array field timermessage, coru, sem, op, receiver, currevent, baseevent, prevevent; <* variables defining the size of basic entities (descriptors) *> integer corusize, semsize, simsize, opheadsize; integer array clockmess(1:2); real array clock(1:3); boolean eventqueueempty; message trim variables; algol list.on; integer no_of_terminals,max_children,cur_children, child_base_address,childrencreated,termdisconnect, oscommunication,osparentmess, length_user_cat_entry, length_user_cat_entry0,size_user_cat, user_cat_users, con_desc_size, no_of_drums,no_of_discs,no_of_bs, core_block_size,no_of_core_blocks, first_user_core, reader,punch,console1,console2,firstmt,lastmt,firstterminal, lastterminal,lastdevice, sysconpda, ownbuf,ownarea,owninternal, freebuf,freearea,freeinternal, user_cat_lower,user_cat_upper, cat_sem,z_sem; integer field base_ref; integer array field cat_base_ref,std_base_ref,max_base_ref, core_address_ref,own_ref, first_bs_ref,size_bs_ref; long field run_time_ref,start_time_ref; integer field buf_area_ref,int_func_ref,parent_ref; boolean field state_ref; integer bit_0,bit_batch,bit_abs_size,bit_std_base, bit_evening,bit_maxclaim,bit_auto,bit_waiting, bit_c1,bit_priv,tw_mask; boolean bit_mess,bit_answer,bit_wait, bit_run ,bit_stop ,bit_start, bit_proc,bit_not_run,mon_list,mon_change; integer std_buf,std_area,std_int,std_func,std_size, std_temp_entries, std_entries,std_segm_disc,std_segm_disc1, std_entry_disc,std_entry_disc1; integer std_max_buf,std_max_area,std_max_int,std_max_size, std_max_entries,std_max_segm_disc,std_max_segm_disc1, std_max_entry_disc,std_max_entry_disc1, own_entries,own_entry_disc,own_segm_disc, own_entry_disc1,own_segm_disc1; long array drum_name,std_disc_name,std_disc1_name, user_cat_name,own_drum,own_disc,own_disc1, std_program, own_name,name1,name(1:3); long array field laf; integer array field iaf; real array field raf; integer i,j,k; integer field con_access,con_prio_and_commands, con_first_address,con_top_address,con_buf_and_area, con_job_id, con_int_and_func,con_mode, con_lower_max,con_upper_max,con_lower_std,con_upper_std, con_size,con_lower_user,con_upper_user,con_projno, con_usercat_no,con_job_state, con_term_pda, con_cur_child,con_cur_child_pda, con_term_no,con_ref,con_proc_in,con_proc_out, con_job; integer array field cur_con_desc,con_first_bs,fi; long array field con_proc_name,con_program, con_des_term, con_in_name,con_out_name,con_term_name,con_job_name; integer maxpmess,maxmess; boolean array testop(1:12); long array sysconsole,logconsole,monitorconsole(1:3); integer array tail(1:10); long array field doc; array field f; boolean lock; algol list.off; algol copy.tmonpr; message error messages: trim variable; integer size_error_message; message batch queue: trim variables and fields; algol list.on; integer qdescsize,qdes,b_max_jobs,b_curjob, b_child_first,b_child_last, b_max_time, b_max_time_day, b_max_size_day, b_max_time_night,b_max_size_night, b_day_to_night, b_night_to_day, b_upd_time,b_interval,b_time_slice,b_std_time, b_max_children,b_cur_children,b_job_number, b_run_children,b_stop_begin,b_stop_end, swop_segm, b_max_prio_day; real b_time_fac,b_job_fac; integer field q_jobmask, q_job_no,q_job_state,q_job_seq,q_max_time, q_start_time, q_remove_job_file,q_lref; long array field q_job_name,q_printer,q_wrk_o, d_job_name; integer field q0_max_time_day,q0_max_size_day, q0_max_time_night,q0_max_size_night, q0_day_to_night,q0_night_to_day, q0_upd_time; long array qname,swop,swopdoc(1:3); algol list.off; message primary input: global definitions; integer array field l_line_buf; integer field l_next,l_type; long array field l_procname,l_jobname,l_outname,l_printer,l_last; maxsem:= maxsemch:= maxop:= maxcoru:= maxnettoop:= 0; maxmessext:= maxprocext:= 1; corusize:= 20; simsize:= 6; semsize:= 8; opheadsize:= 8; testbuffering:= 1; timeinterval:= 5; message trimming; algol list.on; lock:=true; bit_0 :=(1 shift 0); bit_batch :=(1 shift 1); bit_abs_size:=(1 shift 2); bit_std_base:=(1 shift 3); bit_evening :=(1 shift 4); bit_maxclaim:=(1 shift 5); bit_auto :=(1 shift 6); bit_waiting :=(1 shift 7); bit_c1 :=(1 shift 8); bit_priv :=(1 shift 9); twmask:=-1; <*mask for typewriters in call of open*> <*bits for process state*> bit_mess :=false add (1 shift 0); bit_answer :=false add (1 shift 1); bit_wait :=false add (1 shift 2); bit_run :=false add (1 shift 3); bit_stop :=false add (1 shift 4); bit_start :=false add (1 shift 5); bit_proc :=false add (1 shift 6); bit_not_run:=false add (1 shift 7); state_ref :=12; <*process state*> buf_area_ref:=28; int_func_ref:=30; parent_ref:=52; std_base_ref:=76; max_base_ref:=72; cat_base_ref:=68; core_address_ref:=22; start_time_ref:=60+2; run_time_ref:=56+2; base_ref:=100; <*base register*> firstbs_ref:=86; size_bs_ref:=18; i:=0; i:=con_access:=i+2; i:=con_prio_and_commands:=i+2; i:=con_proc_name:=i; i:=con_first_address:=i+2+8; i:=con_top_address:=i+2; i:=con_buf_and_area:=i+2; i:=con_int_and_func:=i+2; i:=con_mode:=i+2; i:=con_lower_max:=i+2; i:=con_upper_max:=i+2; i:=con_lower_std:=i+2; i:=con_upper_std:=i+2; i:=con_size:=i+2; i:=con_program:=i; i:=con_lower_user:=i+2+8; i:=con_upper_user:=i+2; i:=con_projno:=i+2; i:=con_user_cat_no:=i+2; i:=con_in_name:=i; i:=con_out_name:=i+8; i:=con_term_name:=i+8; i:=con_jobstate:=i+10; i:=con_job_id:=i+2; con_first_bs:=con_desc_size:=i+10; doc:=2; fi:=f:=0; readsfp(<:c:>,logconsole.f,<:c:>); for i:=1 step 1 until 12 do testop(i):=false; connectlso; for i:=1 step 1 until 11 do begin if testop(i) then write(out,"nl",1,<:*test :>,case i of ( <:init:>,<:create:>,<:verify:>,<:usercat:>, <:communication:>,<:error:>,<:batch:>,<:submit:>, <:job:>,<:primary in:>,<:queue selection:>)); end; outendcur(10); readsfp(<:cat:>,usercatname.f,<:osusercat:>); std_program(1):=long <:fp:>; std_program(2):= sysconsole(2):=logconsole(2):=monitorconsole(2):= drumname(2):=stddiscname(2):=stddisc1name(2):=0; curchildren:=0; maxmess:=5; maxpmess:=5; console1:=2; ownbuf:=2; ownarea:=2; owninternal:=1; child_base_address:=128*1024; algol list.on copy.tramoption; ownbuf:=ownbuf+noofterminals; readifp(<:children:>,maxchildren,maxchildren); readifp(<:blocks:>,noofcoreblocks,noofcoreblocks); if maxchildren<noofcoreblocks then maxchildren:=noofcoreblocks; readifp(<:size:>,coreblocksize,coreblocksize); readifp(<:terminals:>,no_of_terminals,no_of_terminals); i:=lookupentry(logconsole,tail); if i<>0 then alarm("nl",1,logconsole,<: does not exist:>,i); for i:=1,2 do logconsole(i):=tail.doc(i); write(out,<:log console is :>,logconsole); if readsfp(<:monitor:>,name.f,<::>) then readsfp(<:monitor:>,monitorconsole.f,<::>); write(out,"nl",1,<:monitor console :>,monitorconsole); name(1):=0; set_cat_base(name,usercatlower,usercatupper); i:=connectcuri(usercatname); if i<>0 then alarm("*",3,usercatname,<: connect error :>,i); setposition(in,0,0); inrec6(in,512); length_user_cat_entry:=in.fi(2); length_user_cat_entry0:=in.fi(3); size_user_cat:=in.fi(4); user_cat_users:=in.fi(5); unstackcuri; no_of_bs:=no_of_drums+no_of_discs; if no_of_bs*12+14<>lengthusercatentry0 then alarm("nl",1, <:***number of bs devices inconsistent:>,no_of_bs); i:=condescsize:=condescsize+size_bs_ref*(no_of_drums+no_of_discs); i:=con_proc_in:=i+4; i:=con_proc_out:=i+2; i:=con_term_pda:=i+2; i:=con_des_term:=i; i:=con_job_name:=i+8; i:=con_cur_child:=i+2+8; i:=con_cur_child_pda:=i+2; i:=con_term_no:=i+2; i:=con_ref:=i+2; i:=con_job:=i+2; condescsize:=i; algol list.off; message error message: initialize trim; size_error_message:=200; message batch queue: initialization; algol list.on; d_job_name:=4; i:=qdescsize:=condescsize; i:=q_jobno:=i+2; i:=q_jobmask:=i+2; i:=q_job_state:=i+2; i:=q_job_seq:=i+2; i:=q_max_time:=i+2; i:=q_start_time:=i+2; i:=q_remove_job_file:=i+2; i:=q_lref:=i+2; i:=q_job_name:=i; i:=q_printer:=i+8; i:=q_wrk_o:=i+8; i:=qdescsize:=i+8; <*global information*> i:=q0_max_time_day:=con_desc_size+2; i:=q0_max_size_day:=i+2; i:=q0_max_time_night:=i+2; i:=q0_max_size_night:=i+2; i:=q0_night_to_day:=i+2; i:=q0_day_to_night:=i+2; i:=q0_upd_time:=i+2; qname(1):=long <:bqueu:> add 'e'; qname(2):=0; b_max_time_day:=20*60; <*sec*> b_max_time_night:=8*60*60; b_max_size_day:=512*coreblocksize; b_cur_job:=0; b_maxjobs:=250; b_max_children:=1; b_std_time:=5*60; b_time_slice:=30; b_interval:=5; swop(1):=long <:bswop:>; swop(2):=0; for i:=1,2 do swopdoc(i):=owndisc(i); b_time_fac:=0.5; b_job_fac :=1.0; algol copy.batchtrim; readifp(<:btimeslice:>,b_time_slice,b_time_slice); b_max_prio_day:=2*b_max_time_day; readifp(<:bprio:>,b_max_prio_day,b_max_prio_day); readrfp(<:btimefac:>,btimefac,btimefac); readrfp(<:bjobfac:>,bjobfac,bjobfac); readifp(<:bchildren:>,bmaxchildren,bmaxchildren); readifp(<:bjobs:>,bmaxjobs,bmaxjobs); readifp(<:bstdtime:>,bstdtime,bstdtime); readifp(<:time:>,b_max_time_day,b_max_time_day); laf:=2; swopsegm:=bmaxchildren*bmaxsizenight//512+1; b_curchildren:=0; qdes:=b_maxchildren+1; b_job_number:=0; if readifp(<:bsize:>,bmaxsizeday,bmaxsizeday) then bmaxsizeday:=bmaxsizeday*1024; <*halfwords*> algol list.off; message primary input: initialization of globals; i:=l_next:=2; i:=l_type:=i+2; i:=l_procname:=i; i:=l_jobname:=i+8; i:=l_outname:=i+8; i:=l_printer:=i+8; i:=l_last:=i+8; message tramos trim: claiming basic; maxsem:=maxsem+3+maxchildren; message readcommand: claiming basic; maxcoru:=maxcoru+noofterminals+maxmess; maxsem:=maxsem+no_of_terminals; maxsemch:=maxsemch+1; maxop:=maxop+noofterminals+1; maxnettoop:=maxnettoop+8*(noofterminals+1); maxprocext:=maxprocext+1; maxmessext:=maxmessext+noofterminals; message parent message: claiming basic; maxcoru:=maxcoru+1; maxsemch:=maxsemch+1; maxop:=maxop+maxpmess; maxnettoop:=maxnettoop+8*maxpmess; message batch que: claiming basic; maxcoru:=maxcoru+4; maxsemch:=maxsemch+2; maxop:=maxop+qdes+b_max_jobs+4; maxnettoop:=maxnettoop+12*qdes+6*(bmaxjobs+4); maxsem:=maxsem+qdes+1; maxmessext:=maxmessext+1; message primary input: claiming basic; maxcoru:=maxcoru+1; maxprocext:=maxprocext+1; begin <* work variables - primarily used during initialization *> integer array field simref, semref, coruref, opref; integer proccount, corucount, messcount, cmi, cmj; integer array zoneia(1:20); <* field variables describing the format of basic entities *> integer field <* chain head *> next, prev, <* simple semaphore *> simvalue, simcoru, <* chained semaphore *> semop, semcoru, <* coroutine *> coruop, corutimerchain, corutimer, corupriority, coruident, <* operation head *> opnext, opsize; boolean field corutypeset, corutestmask, optype; real starttime; long corustate; <* field variables used as queue identifiers (addresses) *> integer array field current, readyqueue, idlequeue, timerqueue; <* extensions (message- and process- extensions) *> integer array messref, messcode, messop (1:maxmessext); integer array procref, proccode, procop (1:maxprocext); <* core array used for accessing the core using addresses as field variables (as delivered by the monitor functions) - descriptor array 'd' in which all basic entities are allocated (except for extensions) *> integer array core (1:1), d (1:(4 <* readyqueue *> + 4 <* idlequeue *> + 4 <* timerqueue *> + maxcoru * corusize + maxsem * simsize + maxsemch * semsize + maxop * opheadsize + maxnettoop)/2); <*************** initialization procedures ***************> procedure initchain (chainref); value chainref; integer array field chainref; begin integer array field cref; cref:= chainref; d.cref.next:= d.cref.prev:= cref; end; <***** nextsem ***** this procedure allocates and initializes the next simple semaphore in the pool of claimed semaphores. the procedure returns the identification (the address) of the semaphore to be used when calling 'signal', 'wait' and 'inspect'. *> integer procedure nextsem; begin nextsem:= simref; if simref >= firstsem then initerror(1, true); initchain(simref + simcoru); d.simref.simvalue:= 0; simref:= simref + simsize; end; <***** nextsemch ***** this procedure allocates and initializes the next simple semaphore in the pool of claimed semaphores. the procedure returns the identification (the address) of the semaphore to be used when calling 'signalch', 'waitch' and 'inspectch'. *> integer procedure nextsemch; begin nextsemch:= semref; if semref >= firstop-4 then initerror(2, true); initchain(semref + semcoru); initchain(semref + semop); semref:= semref + semsize; end; <***** nextcoru ***** this procedure initializes the next coroutine description in the pool of claimed coroutine descriptions. at initialization is defined the priority (an integer value), an identi- fication (an integer value 0..8000) and a test pattern (a boolean). *> integer procedure nextcoru(ident, priority, testmask); value ident, priority, testmask; integer ident, priority; boolean testmask; begin corucount:= corucount + 1; if corucount > maxcoru then initerror(3, true); nextcoru:= corucount; initchain(coruref + next); initchain(coruref + corutimerchain); initchain(coruref + coruop); d.coruref.corupriority:= priority; d.coruref.coruident:= ident * 1000 + corucount; d.coruref.corutypeset:= false; d.coruref.corutimer:= 0; d.coruref.corutestmask:= testmask; linkprio(coruref, readyqueue); current:= coruref; coruref:= coruref + corusize; end; <***** nextop ***** this procedure initializes the next operation in the pool of claimed ope- rations (heads and buffers). the head is allocated and immediately following the head is allocated 'size' halfwords forming the operation buffer. the procedure returns an identification of the operation (an address) and in case this address is held in a field variable 'op', the buffer area may be accessed as: d.op(1), d.op(2), d.op(3) ... *> integer procedure nextop (size); value size; integer size; begin nextop:= opref; if opref >= optop then initerror(4, true); initchain(opref + next); d.opref.opsize:= size; opref:= opref + size + opheadsize; end; <***** nextprocext ***** this procedure initializes the next process extension in the series of claimed process extensions. the process description address is put into the process extension and the state of the extension is initialized to be closed. *> integer procedure nextprocext (processref); value processref; integer processref; begin proccount:= proccount + 1; if proccount >= maxprocext then initerror(5, true); nextprocext:= proccount; procref(proccount):= processref; proccode(proccount):= 1 shift 12; end; <***** initerror ***** this procedure is activated in case the initialized set of resources does not match the claimed set. in case more resources are claimed than used, a warning is written, in case too few resources are claimed, an error message is written and the execution is terminated. *> procedure initerror (resource, exceeded); value resource, exceeded; integer resource; boolean exceeded; begin write(out, false add 10, 1, if exceeded then <:more :> else <:less :>, case resource of ( <:simple semaphores:>, <:chained semaphores:>, <:coroutines:>, <:operations:>, <:process extensions:>), <: initialized than claimed:>, false add 10, 1); if exceeded then goto dump; end; <***** stackclaim ***** this procedure is used by a coroutine from its first activation to it arrives its first waiting point. the procedure is used to claim an addi- tional amount of stack space. this must be done because the maximum stack space for a coroutine is set to be the max amount used during its very first activation. *> procedure stackclaim (size); value size; integer size; begin boolean array stackspace (1:size); end; message tramos trim global variables and procedures; algol list.on; integer logsem; boolean free,stopsystem; zone log(128,1,noerror),cat(768,2,stderror),z(128,1,stderror); long array basestack(1:25); long array field basep,maxbasep; integer array con_pda_table(1:no_of_terminals), con_desc(1:no_of_terminals*con_desc_size//2), chartable(0:255),user_core(1:256*coreblocksize*noofcoreblocks), usercatbs(1:6*no_of_bs),ownbs,freebs(1:8*no_of_bs), perm_bs_claimed(1:usercatusers+10,1:noofbs,1:4), <*+10 to allow some updating of the usercatalog while running*> includelist(0:lastdevice), coretable(1:no_of_core_blocks+1,1:2), childtable(1:(maxchildren+1)*20); boolean array bs_exist(1:no_of_bs+1); <*use of childtable 1: childpda 2: destermpda 3: state (1 created, 2 running, 3 stopped, 4 breaked, 5 swopped 4: ref to descriptor 5: jobname 6: - 7: - 8: - 9: batch or online (0=online, 1=batch) 10: first address 11: last address 12: job number 13: segment number swop 14: segment number batch queue 15: buffer ref finis or break 16: childno 17: usercatno 18: process description in 20: access semaphore 19: process description out *> integer field ct_child_pda, ct_term_pda, ct_state, ct_ref, ct_batch, ct_first, ct_last, ct_jobno, ct_segm_swop, ct_segm_queue, ct_bufref,ct_childno,ct_usercatno, ct_procin,ct_procout,ct_sem; integer state_created,state_running,state_stopped, state_breaked,state_swopped,state_removed, ct_size; long array field ct_job_name; procedure set_base(lower,upper); value lower,upper; integer lower,upper; begin integer res; long array name(1:2); integer array field lu; name(1):=0; lu:=0; if basep>=maxbasep then alarm("nl",1,<:base pointer:>) else begin res:=set_cat_base(name,lower,upper); if res>0 then alarm("nl",1,<:base interval:>,res,lower,upper,basep) else begin basestack.basep.lu(1):=lower; basestack.basep.lu(2):=upper; basep:=basep+4; end set cat base; end no stack over flow; end set base; procedure resetbase; begin integer res; long array name(1:2); integer array field lu; name(1):=0; lu:=0; if basep=0 then set_base_std else begin basep:=basep-4; res:=set_cat_base(name,basestack.basep.lu(1),basestack.basep.lu(2)); if res<>0 then alarm("nl",1,<:reset base :>,res,basep); end basep>0; end reset_base; procedure set_base_std; begin setbase(core.ownref.stdbaseref(1),core.ownref.stdbaseref(2)); end; procedure set_base_user_cat; begin setbase(usercatlower,usercatupper); end; procedure set_own_bs(doc,claim,owndoc,ownsegm,ownentry); value ownsegm,ownentry; integer ownsegm,ownentry; long array doc,owndoc; integer array claim; if doc(1)<>owndoc(1) or doc(2)<>owndoc(2) then begin integer i; for i:=1 step 1 until 8 do claim(i):=0; end else begin integer i; for i:=2 step 2 until 8 do begin claim(i-1):=ownentry; claim(i ):=ownsegm; end end setownbs; integer procedure find_term(pda); value pda; integer pda; if pda=0 then findterm:=-1 else begin integer i,j; findterm:=i:=0; j:=no_of_terminals+1; for i:=i+1 while i<=no_of_terminals and j=no_of_terminals+1 do if con_pda_table(i)=pda then j:=findterm:=i; cur_con_desc:=(j-1)*con_desc_size; end findterm; integer procedure next_free_term(pda); value pda; integer pda; if pda=0 then next_free_term:=-1 else begin integer i,j,k; long array field name; i:=next_free_term:=0; j:=no_of_terminals+1; for i:=i+1 while i<=no_of_terminals and j=no_of_terminals+1 do if con_pda_table(i)=0 or con_pda_table(i)=pda then begin j:=nextfreeterm:=i; con_pda_table(j):=pda; cur_con_desc:=(j-1)*con_desc_size; condesc.curcondesc.contermpda:=pda; name:=pda+2; for k:=1,2 do condesc.curcondesc.condesterm(k):=core.name(k); condesc.curcondesc.contermno:=i; end found; end next free term; procedure noerror(z,s,b); zone z; integer s,b; begin comment no action; end; procedure writelog(t1,i,t2); string t1,t2; integer i; begin wait(logsem); write(log,t1,i,"sp",1,t2,"nl",1); setposition(log,0,0); signal(logsem); end; algol list.off; message readcommand global variables and procedures; algol list.on; integer ownpda,tpspda; integer messaddress,attline; boolean att,verify; zone array c_buf(no_of_terminals,17,1,no_error); algol copy.tchildpr; algol copy.treaduscat; algol copy.treadclist; algol copy.tnextparam; procedure readcommand(cno); value cno; integer cno; begin integer rem,pda,termno,el; integer array field cur; boolean stop,waitc; integer array field attref; stackclaim(850); stop:=false; repeat waitc:=waitch(attline,attref,att or stopsystem,0); if (stopsystem and waitc) extract 12 =0 then begin pda:=d.attref(1); termno:=findterm(pda); if termno=0 then termno:=nextfreeterm(pda); cur:=curcondesc; inspect(condesc.cur.conaccess,el); wait(condesc.cur.conaccess); readcommandlist(c_buf(termno),condesc.curcondesc,false); signal(condesc.cur.conaccess); signalch(attline,attref,free); end else stop:=true; until stop; writelog(<:readcommand:>,cno,<:stopped:>); end readcommand; procedure receivemess(no); value no; integer no; begin boolean stop; integer array M,A(1:8); integer array field taddress; integer array field bufref,attref,pmessref; stackclaim(350); stop:=false; repeat cwaitmessage(messaddress,M,bufref,0); taddress:=core.bufref(4); if taddress<0 then sendanswer(1,bufref,A) else if core.taddress(1)=0 then begin <*parent message*> waitch(pmessline,pmessref,free,0); d.pmessref(1):=taddress; d.pmessref(2):=bufref; signalch(pmessline,pmessref,pmess); osparentmess:=osparentmess+1; end else begin sendanswer(1,bufref,A); waitch(attline,attref,free,0); d.attref(1):=taddress; signalch(attline,attref,att or (stop and stopsystem)); oscommunication:=oscommunication+1; end terminal; until stop; writelog(<:receivemess:>,0,<:finis:>); end receivemess; algol list.off; message parent message global variables and procedures; algol list.on; boolean pmess; integer pmessline; algol list.on copy.treadjob; procedure receive_parent_message; begin integer i,j,res,cbn,op,mode,word,job; integer array M,A(1:8); integer array field bufref,parentref,child_pda,cur,fi, bufd,reg,ct,bref; long array field nf; integer field interrupt_address; long array name,text(1:3); boolean pause,batch; zone pz(17,1,noerror); stackclaim(750); interruptaddress:=38; for i:=1 step 1 until 8 do A(i):=0; fi:=0; repeat waitch(pmessline,parentref,pmess,0); bufref:=d.parentref(2); child_pda:=core.bufref(4); if childpda<0 then send_answer(1,bufref,A) else begin cbn:=0; ct:=-ct_size; repeat cbn:=cbn+1; ct:=ct+ct_size; until cbn>maxchildren or childpda=childtable.ct.ct_childpda; if cbn<=maxchildren then wait(childtable.ct.ct_sem); if cbn>maxchildren or childtable.ct.ct_childpda<>childpda then sendanswer(2,bufref,A) else begin <*it was a child*> op:=core.bufref(5) shift (-12) extract 12; mode:=core.bufref(5) extract 12; pause:=mode extract 1=1; if op mod 2=1 or op>42 then sendanswer(3,bufref,A) else if op=0 then sendanswer(1,bufref,A) else begin nf:=childpda+2; for i:=1,2 do name(i):=core.nf(i); cur:=childtable.ct.ct_ref; <*console description*> batch:=childtable.ct.ct_batch>0; if op//2<3 then childtable.ct.ct_bufref:=bufref; if batch then begin open(pz,8,q.cur.condesterm,tw_mask); if pause then begin waitch(bmessline,bref,free,0); d.bref(1):=1; <*signal to clock driver*> d.bref(2):=-1; <*stop*> d.bref(3):=ct; signalch(bmessline,bref,cmess); end pause; end else begin wait(condesc.cur.conaccess); if condesc.cur.concurchildpda<>childpda then begin for i:=1,2 do condesc.cur.conprocname(i):=name(i); condesc.cur.concurchildpda:=childpda; condesc.cur.concurchild:=childtable.ct.ct_childno; end; open(pz,8,condesc.cur.condesterm,tw_mask); if pause then res:=stopchild(condesc.cur); end; write(pz,"nl",1,if pause then <:pause:> else <:message:>, "sp",1,name,"sp",1); op:=op//2; mode:=mode shift (-5); text(2):=0; bufd:=bufref+10; for i:=1 step 1 until 7 do begin word:=core.bufd(i); if mode shift (i-7)=1 then write(pz,word) else begin text.fi(1):=word; text.fi(2):=0; write(pz,text); if word=0 then write(pz,"sp",1); end text; end write buffer content; if op<3 then childtable.ct.ct_bufref:=bufref; case op of begin begin <*finis*> if batch then begin waitch(bmessline,bref,free,0); d.bref(1):=1; <*clock*> d.bref(2):=-5; <*finis*> d.bref(3):=ct; signalch(bmessline,bref,cmess); end batch else begin res:=stopchild(condesc.cur); if res<>0 then disable write(pz,<:**stop int :>,condesc.cur.conprocname,res); res:=removechild(condesc.cur,pz); if res<>0 then write(pz,<:**remove error :>,name,res, childtable.ct.ct_state); end online; end finis; begin <*break*> if core.childpda(40+7)>0 and core.childpda(40+7)<18 then write(pz,core.childpda(40+7),<: ic :>,core.childpda(40+6), <: w0 :>,core.childpda(41), <: w1 :>,core.childpda(42), <: w2 :>,core.childpda(43), <: w3 :>,core.childpda(44)); if batch then begin waitch(bmessline,bref,free,0); d.bref(1):=1; d.bref(2):=-4; d.bref(3):=ct; signalch(bmessline,bref,cmess); end else begin res:=stopchild(condesc.cur); childtable.ct.ct_state:=state_breaked; end; end break; begin <*hard error*> end hard error; begin <*account*> end account; begin <*replace*> end replace; begin <*new job*> read_job_file(ct,bufref,A,pz); end newjob; begin <*mount tape*> end mount; begin <*print*> end print; begin <*mount ring*> end ring; begin <*suspend tape*> end suspend; begin <*release tape*> end release; begin <*load*> end load; begin <*change paper*> end change; begin <*timer*> end timer; begin <*convert*> end convert; begin <*mount special*> end mount special; begin <*mount kit*> end kit; begin <*lock*> lock:=true; end lock; begin <*open*> lock:=false; end open; begin <*remove*> end remove; begin <*swop and wait*> end swop and wait; end case; if op>=3 then sendanswer(1,bufref,A); if -,batch then signal(condesc.cur.conaccess); close(pz,true); end legal operation; end it was a child; if cbn<=maxchildren then signal(childtable.ct.ctsem); end childpda>0; signalch(pmessline,parentref,free); until false; end parent message; algol list.off; message error message: global variables and procedures,; algol list.on; long array error_texts(1:sizeerrormessage); long array field error_ready,error_syntax,error_not_allowed, error_no_core, error_no_buffers,error_no_areas,error_no_internals, error_process_unknown,error_process_exists, error_catalog_error,error_area_unknown, error_area_reserved,error_program_too_big, error_area_error,error_device_unknown, error_device_reserved,error_not_implemented, error_bs_claims_exceeded,error_bs_device_unknown, error_name_unknown,error_no_entries_in_maincat, error_illegal_priority,error_program_name_unknown, error_name_conflict, error_result_impossible,error_job_file_unknown, error_job_number_not_found; procedure init_error_text(e); long array e; begin integer array field p,max_error; integer i,j; integer array f(1:sizeerrormessage); array field t; long array field lf; <* an error record lookup like this: +0 param(1) +2 param(2) +4 param(3) +6 error text where the value of param indicates: param(i)=<=0 dummy 1 integer >1 reference to a text *> for i:=1 step 1 until size_error_message do e(i):=0; j:=1; i:=t:=f(j):=error_ready:=6; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:ready:>); i:=t:=f(j):=error_syntax:=12+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:***syntax:>); i:=t:=f(j):=error_not_allowed:=16+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:not allowed:>); i:=t:=f(j):=error_no_core:=16+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:no core:>); i:=t:=f(j):=error_no_buffers:=16+i; j:=j+1; p:=i-6; e.p(1):=1;e.p(2):=e.p(3):=-1; movestring(e.t,1,<:no buffers:>); i:=t:=f(j):=error_no_areas:=16+i; j:=j+1; p:=i-6; e.p(1):=-1;e.p(2):=1;e.p(3):=-1; movestring(e.t,1,<:no areas:>); i:=t:=f(j):=error_no_internals:=16+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=-1;e.p(3):=1; movestring(e.t,1,<:no internals:>); i:=t:=f(j):=error_process_unknown:=16+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:process unknown:>); i:=t:=f(j):=error_process_exists:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:process exists:>); i:=t:=f(j):=error_catalog_error:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:catalog error:>); i:=t:=f(j):=error_area_unknown:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:area unknown:>); i:=t:=f(j):=error_area_reserved:=16+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:area reserved:>); i:=t:=f(j):=error_program_too_big:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:program too big:>); i:=t:=f(j):=error_area_error:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:area error:>); i:=t:=f(j):=error_device_unknown:=16+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:device unknown:>); i:=t:=f(j):=error_device_reserved:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:device reserved:>); i:=t:=f(j):=error_not_implemented:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:not implemented:>); i:=t:=f(j):=error_bs_claims_exceeded:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:bs claims exceded:>); i:=t:=f(j):=error_bs_device_unknown:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:bs device unknown:>); i:=t:=f(j):=error_name_unknown:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:name unknown:>); i:=t:=f(j):=error_no_entries_in_maincat:=20+i;j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:no entries in main catalog:>); i:=t:=f(j):=error_illegal_priority:=32+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:illegal priority:>); i:=t:=f(j):=error_program_name_unknown:=20+i; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:progran name unknown:>); i:=t:=f(j):=error_name_conflict:=i+28; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:name conflict:>); i:=t:=f(j):=error_result_impossible:=i+24; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:result impossible:>); i:=t:=f(j):=error_job_file_unknown:=i+20; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:job file unknown:>); i:=t:=f(j):=error_job_number_not_found:=i+20; j:=j+1; p:=i-6; e.p(1):=e.p(2):=e.p(3):=-1; movestring(e.t,1,<:job number not found:>); end init error; procedure writeerror(z,error,auxerror); long array field error; zone z; integer array auxerror; begin long array field lf; integer array field p; p:=error-6; write(z,errortexts.error); if error=error_bs_claims_exceeded then begin for i:=1 step 1 until no_of_bs do begin if auxerror(i)>0 then begin lf:=i*12-12; write(z,"nl",1,"sp",2,true,7,usercatbs.lf); end; end for; end error=bsclaim else begin for i:=1,2,3 do begin if errortexts.p(i)>0 then begin if errortexts.p(i)=1 then write(z,auxerror(i)) else begin lf:=errortexts.p(i); write(z,"sp",1,auxerror.lf); end text; end param; end for; end error<>bs; end write error; algol list.off; message batch queue global variables and procedures; algol list.on; integer array q(1:qdes*qdescsize//2); integer array b_segm_table(1:b_maxchildren,1:2); integer array job_table(1:b_maxjobs,1:13); <* 1: segment number 2: state (0: free, 1: enrolled, 2: running, 3: removed) 3: unique job number 4: current job priority 5: run time 6: rest time 7: childno 8: termpda 9: jobprio 10: projno 11: cpu time 12: sequence number 13: job mask (0=normal, 1=released, 2=evening) *> zone qz,q_in(128,1,noerror); real timebase; boolean cmess,qmess,bmess,jobtimermess,newqueue,day; integer qmessline,bmessline,qsem; algol list.on copy.treadsub; procedure init_batch_queue; begin if -,newqueue then begin integer array field bref; integer segm; get_job_segm_0(false); for segm:=1 step 1 until b_max_jobs do begin if get_job_segm(q,segm,false) then begin <*old job found*> if q.q_job_state=staterunning then begin disable write(out,"nl",1,true,12,q.qjobname,q.qjobno,<: lost:>); q.q_job_state:=q.qjobno:=0; get_jobsegm(q,segm,true); end else begin b_cur_job:=b_cur_job+1; jobtable(segm,1):=segm; jobtable(segm,2):=q.q_job_state; jobtable(segm,3):=q.q_job_no; jobtable(segm,4):=q.q_maxtime; jobtable(segm,5):=q.qmaxtime; jobtable(segm,6):=q.qmaxtime; jobtable(segm,7):=0; jobtable(segm,8):=q.contermpda; jobtable(segm,9):=q.qmaxtime; jobtable(segm,10):=q.conprojno shift (-8) extract 16; jobtable(segm,11):=0; jobtable(segm,12):=0; jobtable(segm,13):=q.q_jobmask; if bjobnumber<q.fi.q_job_no then b_jobnumber:= q.fi.q_job_no; waitch(bmessline,bref,free,0); d.bref(1):=2; d.bref(2):=segm; signalch(bmessline,bref,bmess); end initjob; end old job; end scan segments; end -,newqueue; disable write(out,"nl",2,<:batch included :>,if newqueue then <:new:> else <:old:>,<: queue :>); disable writetime(out,b_upd_time);; disable write(out,<< dddddd>, "nl",1,<:current max time:>,bmaxtime, if day then <: day:> else <: night:>, "nl",1,<:max time day :>,b_max_time_day//60,<: min:>, b_max_time_day mod 60,<: sec:>, "nl",1,<:max size day :>,b_max_size_day//1024,<: k:>, "nl",1,<:max time night :>,b_max_time_night//60//60,<: h:>, "nl",1,<:max size night :>,b_max_size_night//1024,<: k:>, "nl",1,<:day to night :>,<<_____dd.dd>,b_day_to_night//100, "nl",1,<:night to day :>,b_night_to_day//100, "nl",1,<:parallel jobs :>,<< dddddd>,b_max_children, "nl",1,<:jobs in queue :>,b_cur_job, "nl",1,<:max job number :>,b_job_number); outendcur(10); end initbatch; procedure batch_queue; begin integer i,j,res,cbn,op,mode,word,jobno,jobstate; long array field nf; integer array field qref,qcur,concur,bref,ct; long array name,text(1:3); zone pz(17,1,noerror); stackclaim(800); fi:=0; repeat waitch(qmessline,qref,qmess,0); concur:=d.qref(2); for i:=1,2 do name(i):=condesc.concur.condesterm(i); open(pz,8,name,1 shift 9); open(qin,8,name,1 shift 9); case d.qref(1) of begin begin <*submit*> qcur:=0; j:=condescsize//2; for i:=2 step 1 until j do q.qcur(i):=condesc.concur(i); j:=j+1; for i:=qdescsize//2 step -1 until j do q.qcur(i):=0; res:=0; if d.qref.d_job_name(1)<>0 then begin if readusercat(d.qref.d_jobname,q.qcur,testop(7),pz) then begin stdclaim(q.qcur); stdbs(q.qcur,pz); end else begin res:=4; writeerror(pz,errornameunknown,q.qcur); end; end jobname; if res=0 then read_submit(qin,pz,q.qcur,false); end submit; begin integer t; <*queue*> t:=condesc.concur.contermpda; list_job_table(pz,if t=sysconpda then 0 else t); end queue; begin integer i,jte,rest; boolean first; <*what*> first:=true; for i:=1 step 1 until maxchildren do begin ct:=(i-1)*ctsize; if childtable.ct.ct_batch>0 then begin if first then begin write(pz,"nl"1,if day then <:day :> else <:night :>); writecurtime(pz); write(pz,"nl",1,<:user________:>,<:state____:>, <:jobno__:>,<:time left:>); first:=false; end; jte:=childtable.ct.ct_segm_queue; rest:=jobtable(jte,6); write(pz,"nl",1,true,12,childtable.ct.ct_jobname, true,9,case childtable.ct.ctstate of (<:created:>,<:running:>,<:stopped:>,<:breaked:>, <:swopped:>),<< dddd>,childtable.ct.ctjobno); if rest>0 then write(pz,<< dd >,rest//3600,rest mod 3600 //60, rest mod 60); end batch job; end childtable scan; end what; begin <*search*> i:=0; jobno:=d.qref(3); repeat i:=i+1; until i=bmaxjobs or jobno=jobtable(i,3); if jobno=jobtable(i,3) then begin write(pz,"nl",1,<:job number:>,jobno,<: :>, case jobtable(jobno,2)+1 of ( <:impossible:>,<:enrolled:>,<:running:>,<:removed:>)); end else writeerror(pz,errorjobnumbernotfound,q.qcur); end search; begin <*kill*> i:=0; jobno:=d.qref(3); repeat i:=i+1; until i=bmaxjobs or jobno=jobtable(i,3); if jobno=jobtable(i,3) then begin jobstate:=jobtable(i,2); b_cur_job:=b_cur_job-1; if jobstate=2 then begin waitch(bmessline,bref,free,0); d.bref(1):=1; <*clock*> d.bref(2):=-6; <* kill running job*> d.bref(3):=(jobtable(i,7)-1)*ctsize; signalch(bmessline,bref,cmess); end job running else for j:=2 step 1 until 15 do jobtable(i,j):=0; qcur:=0; q.qcur.qjobno:=0; get_job_segm(q.qcur,i,true); end else writeerror(pz,errorjobnumbernotfound,q.qcur); end kill; begin <*release*> i:=0; jobno:=d.qref(3); repeat i:=i+1; until i=bmaxjobs or jobno=jobtable(i,3); if jobno=jobtable(i,3) then begin <*job no found*> jobtable(i,13):=1; <*released*> end job found else writeerror(pz,errorjobnumbernotfound,q.qcur); end release; begin <*set prio*> i:=0; jobno:=d.qref(3); repeat i:=i+1; until i=bmaxjobs or jobno=jobtable(i,3); if jobno=jobtable(i,3) then begin jobtable(i,4):=0; end else writeerror(pz,errorjobnumbernotfound,q.qcur); end setprio; end case; close(pz,true); close(q_in,true); signalch(qmessline,qref,free); until false; end batch queue; procedure b_timer; begin integer array field bref; real r; stackclaim(250); repeat waitch(bmessline,bref,free,0); delay(b_time_slice); systime(5,0,r); d.bref(1):=1; d.bref(2):=r; signalch(bmessline,bref,cmess); until false; end b_timer; procedure run_job_timer; begin integer array field bref; stackclaim(150); repeat waitch(bmessline,bref,jobtimermess,0); d.bref(1):=2; d.bref(2):=-1; delay(b_time_slice); signalch(bmessline,bref,bmess); until false; end runjobtimer; algol list.on copy.trunbatch; procedure write_b_des(d,z); integer array d; zone z; begin writeentry(d,z,true); write(z,"nl",1,<:job number :>,d.qjobno, "nl",1,<:job state :>,d.qjobstate, "nl",1,<:job seq :>,d.qjobseq, "nl",1,<:max time :>,d.qmaxtime, "nl",1,<:start wanted :>,d.qstarttime, "nl",1,<:job file name:>,d.qjobname, "nl",1,<:printer :>,d.qprinter); end writebdes; algol list.off; message primary input global variables and procedures; algol list.on; integer priminproc,primpda; long array primin(1:3); integer array line_buf(1:bmaxchildren*(l_last//2)); procedure receive_input_message; begin integer i,j,res,cbn,op,mode,next,type,curline, hwreq; integer array M,A(1:8); integer array field bufref,inputref,child_pda,cur,fi, bufd,reg,ct; long array field nf,lref,address; array field f; integer array lrefs(1:8); long array name,text(1:3),line(1:60); zone mon(17,1,noerror); stackclaim(950); open(mon,8,monitorconsole,0); f:=0; address:=firstaddr(line); for i:=1 step 1 until 60 do line(i):=0; lref:=lrefs(1):=0; movestring(line.lref.f,1,<:mode list.yes<10>:>); lref:=lrefs(2):=lrefs(1)+28; movestring(line.lref.f,3,<: = set 50<10>:>); lref:=lrefs(3):=lrefs(2)+28; movestring(line.lref.f,1,<:scope day :>); lref:=lref+8+8; line.lref(1):=long <:<10>:>; lref:=lrefs(4):=lrefs(3)+28; movestring(line.lref.f,1,<:o :>); lref:=lref+4+8; line.lref(1):=long <:<10>:>; lref:=lrefs(5):=lrefs(4)+28; movestring(line.lref.f,1,<:i :>); lref:=lref+4+8; line.lref(1):=long <:<10>:>; lref:=lrefs(6):=lrefs(5)+28; movestring(line.lref.f,1,<:o c<10>:>); lref:=lrefs(7):=lrefs(6)+28; movestring(line.lref.f,3,<:=convert :>); lref:=lref+8+8+8; line.lref(1):=long <:<10>:>; lref:=lrefs(8):=lrefs(7)+28; movestring(line.lref.f,1,<:finis<10>:>); for i:=1 step 1 until 8 do A(i):=0; fi:=0; repeat c_wait_message(priminproc,M,bufref,0); child_pda:=core.bufref(4); if childpda<0 then send_answer(1,bufref,A) else begin cbn:=0; ct:=-ct_size; repeat cbn:=cbn+1; ct:=ct+ct_size; until cbn>maxchildren or childpda=childtable.ct.ct_childpda; if cbn>maxchildren then sendanswer(2,bufref,A) else if childtable.ct.ct_batch=0 then send_answer(2,bufref,A) else begin <*it was a child*> op:=core.bufref(5) shift (-12) extract 12; mode:=core.bufref(5) extract 12; if op=0 then sendanswer(1,bufref,A) else if op<>3 then send_answer(3,bufref,A) else begin nf:=childpda+2; hwreq:=core.bufref(7)-core.bufref(6)+2; for i:=1,2 do name(i):=core.nf(i); cur:=childtable.ct.ct_ref; <*console description*> bufd:=bufref+10; lref:=q.cur.q_lref; next:=line_buf.lref.l_next; type:=line_buf.lref.l_type; curline:=nf:=lrefs(next); if hwreq<28 then begin for i:=1,2,3 do A(i):=0; sendanswer(1,bufref,A); end else begin case next of begin begin <*mode list.yes*> next:=if type=0 then 5 else 2; end 1; begin <* <outname> = set 50*> for i:=1,2 do line.nf(i):=linebuf.lref.l_outname(i); next:=3; end 2; begin <* scope day <outname> *> nf:=nf+8; for i:=1,2 do line.nf(i):=linebuf.lref.l_outname(i); next:=4; end 3; begin <*o <outname> *> nf:=nf+2; for i:=1,2 do line.nf(i):=linebuf.lref.l_outname(i); next:=5; end 4; begin <*i <jobname> *> nf:=nf+2; for i:=1,2 do line.nf(i):=linebuf.lref.l_jobname(i); next:=if type=0 then 8 else 6; end 5; begin <* o c*> next:=7; end 6; begin <* <printer> = convert <outname>*> for i:=1,2 do line.nf(i):=linebuf.lref.l_printer(i); nf:=nf+8+8; for i:=1,2 do line.nf(i):=linebuf.lref.l_outname(i); next:=8; end 7; begin <*finis*> next:=8; end 8; end case next; i:=address+curline; res:=copy(bufref,i,i+28-2); if res<>0 or monw1<28 then A(1):=A(2):=A(3):=0 else begin A(1):=0; A(2):=monw1; A(3):=monw3; linebuf.lref.l_next:=next; end; sendanswer(1,bufref,A); end halwords requested >=28; end legal operation; end it was a child; end childpda>0; until false; end input message; algol list.off; <*************** coroutine monitor procedures ***************> <***** delay ***** this procedure links the calling coroutine into the timerqueue and sets the timeout value to 'timeout'. *> procedure delay (timeout); value timeout; integer timeout; begin link(current, idlequeue); link(current + corutimerchain, timerqueue); d.current.corutimer:= timeout; passivate; d.current.corutimer:= 0; end; <***** pass ***** this procedure moves the calling coroutine from the head of the ready queue down below all coroutines of lower or equal priority. *> procedure pass; begin linkprio(current, readyqueue); passivate; end; <***** signal **** this procedure increases the value af 'semaphore' by 1. in case some coroutine is already waiting, it is linked into the ready queue for activation. the calling coroutine continues execution. *> procedure signal (semaphore); value semaphore; integer semaphore; begin integer array field sem; sem:= semaphore; if d.sem.simvalue < 0 then linkprio(d.sem.simcoru, readyqueue); d.sem.simvalue:= d.sem.simvalue + 1; end; <***** wait ***** this procedure decreases the value of 'semaphore' by 1. in case the value of the semaphore is negative after the decrease, the calling coroutine is linked into the semaphore queue waiting for a coroutine to signal this semaphore. *> procedure wait (semaphore); value semaphore; integer semaphore; begin integer array field sem; sem:= semaphore; d.sem.simvalue:= d.sem.simvalue - 1; linkprio(current, if d.sem.simvalue < 0 then sem+simcoru else readyqueue); passivate; end; <***** inspect **** this procedure inspects the value of the semaphore and returns it in 'elements'. the semaphore is left unchanged. *> procedure inspect (semaphore, elements); value semaphore; integer semaphore, elements; begin integer array field sem; sem:= semaphore; elements:= d.sem.simvalue; end; <***** signalch ***** this procedure delivers an operation at 'semaphore'. in case another coroutine is already waiting for an operation of the kind 'operationtype' this coroutine will get the operation and it will be put into the ready queue for activation. in case no coroutine is waiting for the actial kind of operation it is linked into the semaphore queue. the calling coroutine continues execution. *> procedure signalch (semaphore, operation, operationtype); value semaphore, operation, operationtype; integer semaphore, operation; boolean operationtype; begin integer array field firstcoru, currcoru, op; op:= operation; d.op.optype:= operationtype; firstcoru:= semaphore + semcoru; currcoru:= d.firstcoru.next; while currcoru <> firstcoru do begin if (d.currcoru.corutypeset and operationtype) extract 12 <> 0 then begin link(operation, 0); d.currcoru.coruop:= operation; linkprio(currcoru, readyqueue); link(currcoru + corutimerchain, idlequeue); goto exit; end else currcoru:= d.currcoru.next; end; link(op, semaphore + semop); exit: end; <***** waitch ***** this procedure fetches an operation from a semaphore. in case an operation matching 'operationtypeset' is already waiting at 'semaphore' it is handed over to the calling coroutine. in case no matching operation is waiting, the calling coroutine is linked to the semaphore. in any case the calling coroutine will be stopped and all corouti- nes are rescheduled. *> boolean procedure waitch (semaphore, operation, operationtypeset, timeout); value semaphore, operationtypeset, timeout; integer semaphore, operation, timeout; boolean operationtypeset; begin integer array field firstop, currop; waitch:=false; firstop:= semaphore + semop; currop:= d.firstop.next; while currop <> firstop do begin if (d.currop.optype and operationtypeset) extract 12 <> 0 then begin waitch:=d.currop.optype; link(currop, 0); d.current.coruop:= currop; operation:= currop; linkprio(current, readyqueue); passivate; goto exit; end else currop:= d.currop.next; end; linkprio(current, semaphore + semcoru); if timeout > 0 then begin link(current + corutimerchain, timerqueue); d.current.corutimer:= timeout; end else d.current.corutimer:= 0; d.current.corutypeset:= operationtypeset; passivate; if d.current.corutimer < 0 then operation:= 0 else operation:= d.current.coruop; d.current.corutimer:= 0; currop:= operation; d.current.coruop:= currop; link(current+corutimerchain, idlequeue); exit: end; <***** inspectch ***** this procedure inspects the queue of operations waiting at 'semaphore'. the number of matching operations are counted and delivered in 'elements'. the semaphore is left unchanged. *> procedure inspectch (semaphore, operationtypeset, elements); value semaphore, operationtypeset; integer semaphore, elements; boolean operationtypeset; begin integer array field firstop, currop; integer counter; counter:= 0; firstop:= semaphore + semop; currop:= d.firstop.next; while currop <> firstop do begin if (operationtypeset and d.currop.optype) extract 12 <> 0 then counter:= counter + 1; currop:= d.currop.next; end; elements:= counter; end; <***** csendmessage ***** this procedure sends the message in 'mess' to the process defined by the name in 'receiver', and returns an identification of the message extension used for sending the message (this identification is to be used for calling 'cwait- answer' or 'cregretmessage'. *> procedure csendmessage (receiver, mess, messextension); real array receiver; integer array mess; integer messextension; begin integer bufref, messext; messref(maxmessext):= 0; messext:= 1; while messref(messext) <> 0 do messext:= messext + 1; if messext = maxmessext then <* no resources *> messext:= 0 else begin messcode(messext):= 1 shift 12 add 2; mon(16) send message :(0, mess, 0, receiver); messref(messext):= monw2; if monw2 > 0 then messextension:= messext else messextension:= 0; end; end; <***** cwaitanswer ***** this procedure asks the coroutine monitor to get an answer to the message corresponding to 'messextension'. in case the answer has already arrived it stays in the eventqueue until 'cwaitanswer' is called. in case 'timeout' is positive, the coroutine is linked into the timer queue, and in case the answer does not arrive within 'timout' seconds the coroutine is restarted with result = 0. *> procedure cwaitanswer (messextension, answer, result, timeout); value messextension, timeout; integer messextension, result, timeout; integer array answer; begin integer messext; messext:= messextension; messcode(messext):= messcode(messext) extract 12; link(current, idlequeue); messop(messext):= current; if timeout > 0 then begin link(current + corutimerchain, timerqueue); d.current.corutimer:= timeout; end else d.current.corutimer:= 0; passivate; if d.current.corutimer < 0 then result:= 0 else begin mon(18) wait answer :(0, answer, messref(messextension), 0); result:= monw0; baseevent:= 0; messref(messextension):= 0; end; d.current.corutimer:= 0; link(current+corutimerchain, idlequeue); end; <***** cwaitmessage ***** this procedure asks the coroutine monitor to give it a message, when some- one arrives. in case a message has arrived already it stays at the event queue until 'cwaitmessage' is called. in case 'timeout' is positive, the coroutine is linked into the timer queue, if no message arrives within 'timeout' seconds, the coroutine is restarted with messbufferref = 0. *> procedure cwaitmessage (processextension, mess, messbufferref, timeout); value timeout, processextension; integer processextension, messbufferref, timeout; integer array mess; begin integer i; integer array field messbuf; proccode(processextension):= 2; procop(processextension):= current; link(current, idlequeue); if timeout > 0 then begin link(current + corutimerchain, timerqueue); d.current.corutimer:= timeout; end else d.current.corutimer:= 0; passivate; if d.current.corutimer < 0 then messbufferref:= 0 else begin messbuf:= procop(processextension); for i:=1 step 1 until 8 do mess(i):= core.messbuf(4+i); proccode(procext):= 1 shift 12; messbufferref:= messbuf; baseevent:= 0; end; d.current.corutimer:= 0; link(current+corutimerchain, idlequeue); end; <***** cregretmessage ***** this procedure regrets the message corresponding to messageexten- sion, to release message buffer and message extension. i/o messages are not regretable. *> procedure cregretmessage (messageextension); value messageextension; integer messageextension; begin integer array field messbuf; messbuf:= messref(messageextension); mon(82) regret message :(0, 0, messbuf, 0); messref(messageextension):= 0; end; <***** semsendmessage ***** this procedure sends the message 'mess' to 'receiver' and at the same time it defines a 'signalch(semaphore, operation, operationtype)' to be performed by the monitor, when the answer arrives. in case there are too few resources to send the message, the operation is returned immediately with the result field set to zero. *> procedure semsendmessage (receiver, mess, semaphore, operation, operationtype); value semaphore, operation, operationtype; real array receiver; integer array mess; integer semaphore, operation; boolean operationtype; begin integer array field op; integer messext; op:= operation; messref(maxmessext):= 0; messext:= 1; while messref(messext) <> 0 do messext:= messext + 1; if messext < maxmessext then begin messop(messext):= op; messcode(messext):=1; d.op(1):= semaphore; d.op.optype:= operationtype; mon(16) send message :(0, mess, 0, receiver); messref(messext):= monw2; end; if messext = maxmessext or messref(messext) = 0 <* no resources *> then begin <* return the operation immediately with result = 0 *> d.op(9):= 0; signalch(semaphore, op, operationtype); end; end; <***** semwaitmessage ***** this procedure defines a 'signalch(semaphore, operation, operationtype)' to be performed by the coroutine monitor when a message arrives to the process corresponding to 'processextension'. *> procedure semwaitmessage (processextension, semaphore, operation, operationtype); value processextension, semaphore, operation, operationtype; integer processextension, semaphore, operation; boolean operationtype; begin integer array field op; op:= operation; procop(processextension):= operation; d.op(1):= semaphore; d.op.optype:= operationtype; proccode(processextension):= 1; end; <***** semregretmessage ***** this procedure regrets a message sent by semsendmessage. the message is identified by the operation in which the answer should be returned. the procedure sets the result field of the operation to zero, and then returns it by performing a signalch. *> procedure semregretmessage (operation); value operation; integer operation; begin integer i, j; integer array field op, sem; op:= operation; i:= 1; while i < maxmessext do begin if messref(i) > 0 and (messcode(i) = 1 and messop(i) = op) then begin mon(82) regret message :(0, 0, messref(i), 0); messref(i):= 0; sem:= d.op(1); for j:=1 step 1 until 9 do d.op(j):= 0; signalch(sem, op, d.op.optype); i:= maxmessext; end; i:= i + 1; end; end; <***** link ***** this procedure links an object (allocated in the descriptor array 'd') into a queue of alements (allocated in the descriptor array 'd'). the queues are all double chained, and the chainhead is of the same format as the chain fields of the objects. the procedure links the object immediately after the head. *> procedure link (object, chainhead); value object, chainhead; integer object, chainhead; begin integer array field prevelement, nextelement, chead, obj; obj:= object; chead:= chainhead; prevelement:= d.obj.prev; nextelement:= d.obj.next; d.prevelement.next:= nextelement; d.nextelement.prev:= prevelement; if chead > 0 then <* link into queue *> begin prevelement:= d.chead.prev; d.obj.prev:= prevelement; d.prevelement.next:= obj; d.obj.next:= chead; d.chead.prev:= obj; end else begin <* link onto itself *> d.obj.prev:= obj; d.obj.next:= obj; end; end; <***** linkprio ***** this procedure is used to link coroutines into queues corresponding to the priorities of the actual coroutine and the queue elements. the object is linked immediately before the first coroutine of lower prio- rity. *> procedure linkprio (object, chainhead); value object, chainhead; integer object, chainhead; begin integer array field currelement, chead, obj; obj:= object; chead:= chainhead; currelement:= d.chead.next; while currelement <> chead and d.currelement.corupriority <= d.obj.corupriority do currelement:= d.currelement.next; link(obj, currelement); end; activity(maxcoru); goto initialization; <*************** event handling ***************> takeexternal: currevent:= baseevent; eventqueueempty:= false; repeat current:= 0; prevevent:= currevent; mon(66) test event :(0, 0, currevent, 0); currevent:= monw2; if monw0 < 0 <* no event *> then goto takeinternal; if monw0 = 1 and monw1 > 0 then cmi:= monw1 else cmi:= - monw0; if cmi > 0 then begin <* answer to activity zone *> current:= firstcoru + (cmi - 1) * corusize; linkprio(current, readyqueue); baseevent:= 0; end else if cmi = 0 then begin <* message arrived *> receiver:= core.currevent(3); if receiver < 0 then receiver:= - receiver; procref(maxprocext):= receiver; procext:= 1; while procref(procext) <> receiver do procext:= procext + 1; if procext = maxprocext then begin <* receiver unknown *> <* leave the message unchanged *> end else if proccode(procext) shift (-12) = 0 then begin <* the receiver is ready for accepting messages *> mon(26) get event :(0, 0, currevent, 0); case proccode(procext) of begin begin <* message received by semwaitmessage *> op:= procop(procext); sem:= d.op(1); for cmj:=1 step 1 until 8 do d.op(cmj):= core.currevent(4+cmj); d.op(9):= currevent; signalch(sem, op, d.op.optype); proccode(procext):= 1 shift 12; end; begin <* message received by cwaitmessage *> current:= procop(procext); procop(procext):= currevent; linkprio(current, readyqueue); link(current + corutimerchain, idlequeue); end; end; <* case *> currevent:= baseevent; proccode(procext):= 1 shift 12; end; end <* message *> else if cmi = -1 then begin <* answer arrived *> if currevent = timermessage then begin mon(26) get event :(0, 0, currevent, 0); coru:= d.timerqueue.next; while coru <> timerqueue do begin current:= coru - corutimerchain; d.current.corutimer:= d.current.corutimer - clockmess(2); coru:= d.coru.next; if d.current.corutimer <= 0 then begin <* timer perion expired *> d.current.corutimer:= -1; linkprio(current, readyqueue); link(current + corutimerchain, idlequeue); end; end; mon(16) send message :(0, clockmess, 0, clock); timermessage:= monw2; currevent:= baseevent; end <* timer answer *> else begin messref(maxmessext):= currevent; messext:= 1; while messref(messext) <> currevent do messext:= messext + 1; if messext = maxmessext then begin <* the answer is unknown *> <* leave the answer unchanged - it may belong to an activity *> end else if messcode(messext) shift (-12) = 0 then begin case messcode(messext) extract 12 of begin begin <* answer arrived after semsendmessage *> op:= messop(messext); sem:= d.op(1); mon(18) wait answer :(0, d.op, currevent, 0); d.op(9):= monw0; signalch(sem, op, d.op.optype); messref(messext):= 0; baseevent:= 0; end; begin <* answer arrived after csendmessage *> current:= messop(messext); linkprio(current, readyqueue); link(current + corutimerchain, idlequeue); end; end; end else baseevent:= currevent; end; end; until eventqueueempty; <*************** coroutine activation ***************> takeinternal: current:= d.readyqueue.next; if current = readyqueue then begin mon(24) wait event :(0, 0, baseevent, 0); goto takeexternal; end; corustate:= activate(d.current.coruident mod 1000); cmi:= corustate extract 24; if cmi = 1 then begin <* programmed passivate *> goto takeexternal; end; if cmi = 2 then begin <* implicit passivate in activity *> link(current, idlequeue); goto takeexternal; end; <* coroutine termination (normal or abnormal) *> link(current, idlequeue); goto takeexternal; initialization: <*************** initialization ***************> <* chain head *> prev:= -2; <* -2 prev *> next:= 0; <* +0 next *> <* corutine descriptor *> <* -2 prev *> <* +0 next *> <* +2 (link field) *> corutimerchain:= next + 4; <* +4 corutimerchain *> <* +6 (link field) *> coruop:= corutimerchain + 4; <* +8 coruop *> corutimer:= coruop + 2; <*+10 corutimer *> coruident:= corutimer + 2; <*+12 coruident *> corupriority:= coruident + 2; <*+14 corupriority *> corutypeset:= corupriority + 1; <*+15 corutypeset *> corutestmask:= corutypeset + 1; <*+16 corutestmask *> <* simple semaphore *> <* -2 (link field) *> simcoru:= next; <* +0 simcoru *> simvalue:= simcoru + 2; <* +2 simvalue *> <* chained semaphore *> <* -2 (link field) *> semcoru:= next; <* +0 semcoru *> <* +2 (link field) *> semop:= semcoru + 4; <* +4 semop *> <* operation *> opsize:= next - 6; <* -6 opsize *> optype:= opsize + 1; <* -5 optype *> <* -2 prev *> <* +0 next *> <* +2 operation(1) *> <* +4 operation(2) *> <* +6 - *> <* . - *> <* . - *> trap(dump); systime(1, 0, starttime); for cmi:= 1 step 1 until maxmessext do messref(cmi):= 0; clockmess(1):= 0; clockmess(2):= timeinterval; clock(1):= real <:clock:>; clock(2):= real <::>; mon(16) send message :(0, clockmess, 0, clock); timermessage:= monw2; readyqueue:= 4; initchain(readyqueue); idlequeue:= readyqueue + 4; initchain(idlequeue); timerqueue:= idlequeue + 4; initchain(timerqueue); current:= 0; corucount:= 0; proccount:= 0; baseevent:= 0; coruref:= timerqueue + 4; firstcoru:= coruref; simref:= coruref + maxcoru * corusize; firstsim:= simref; semref:= simref + maxsem * simsize; firstsem:= semref; opref:= semref + maxsemch * semsize + 4; firstop:= opref; optop:= opref + maxop * opheadsize + maxnettoop - 6; for cmi:= coruref step 2 until optop - 2 do d(cmi//2):= 0; reflectcore(core); message tramtrim program; algol list.on; i:=ct_child_pda:=2; i:=ct_term_pda:=i+2; i:=ct_state:=i+2; i:=ct_ref:=i+2; i:=ct_job_name:=i; i:=ct_batch:=i+10; i:=ct_first:=i+2; i:=ct_last:=i+2; i:=ct_jobno:=i+2; i:=ct_segm_swop:=i+2; i:=ct_segm_queue:=i+2; i:=ct_bufref:=i+2; i:=ct_childno:=i+2; i:=ct_usercatno:=i+2; i:=ct_procin:=i+2; i:=ct_procout:=i+2; i:=ct_sem:=i+2; ct_size:=i; state_created:=1; state_running:=2; state_stopped:=3; state_breaked:=4; state_swopped:=5; ownref:=owndescr; laf:=2; for i:=1,2 do ownname(i):=core.ownref.laf(i); basep:=0; maxbasep:=100; setbasestd; free:=false add (1 shift 1); sysconpda:=console; laf:=sysconpda+2; for i:=1,2 do sysconsole(i):=core.laf(i); stopsystem:= false add (1 shift 2); verify:=testop(3); catsem:=nextsem; signal(catsem); zsem:=nextsem; signal(zsem); logsem:=nextsem; signal(logsem); termdisconnect:=oscommunication:=osparentmess:=childrencreated:=0; initalf(chartable); for i:=1 step 1 until usercatusers do for j:=1 step 1 until noofbs do for k:=1,2 do perm_bs_claimed(i,j,k):=0; j:=0; for i:=reader,punch,console1,firstmt step 1 until lastmt, firstterminal step 1 until lastterminal do begin if j<=lastdevice then includelist(j):=i; j:=j+1; end include; lastdevice:=j-1; for i:=(maxchildren+1)*ct_size//2 step -1 until 1 do childtable(i):=0; for i:=1 step 1 until maxchildren do begin iaf:=(i-1)*ctsize; childtable.iaf.ct_childno:=i; childtable.iaf.ct_sem:=nextsem; signal(childtable.iaf.ct_sem); end; firstusercore:=firstaddr(usercore)-1; for i:=1 step 1 until no_of_core_blocks+1 do begin coretable(i,1):=firstusercore+(i-1)*coreblocksize*512; coretable(i,2):=0; <*free*> end; coretable(no_of_core_blocks+1,2):=100000; cleararray(condesc); for i:=1 step 1 until no_of_terminals do con_pda_table(i):=0; open(log,0,logconsole,tw_mask); name(1):=0; readusercat(name,usercatbs,testop(4),log); i:=core.ownref.bufarearef; freebuf:=(i shift (-12) extract 12)-ownbuf; freearea:=(i extract 12)-ownarea; i:=core.ownref.intfuncref; freeinternal:=(i shift (-12) extract 12)-owninternal; for i:=1 step 1 until noofbs do begin iaf:=(i-1)*16; laf:=(i-1)*12; setownbs(usercatbs.laf,ownbs.iaf,owndrum,0,ownentries); setownbs(usercatbs.laf,ownbs.iaf,owndisc,ownsegmdisc,ownentrydisc); setownbs(usercatbs.laf,ownbs.iaf,owndisc1,ownsegmdisc1,ownentrydisc1); end; for i:=1 step 1 until noofbs do begin iaf:=i*16-16; laf:=i*12-12; j:=lookup_bs_claims(ownname,usercatbs.laf,freebs.iaf); bs_exist(i):=j=0; ownbs.iaf(1):=ownbs.iaf(3):=0; if j>0 then write(out,"nl",1,true,12,usercatbs.laf,<: does not exist:>,j) else for j:=1 step 1 until 8 do freebs.iaf(j):=freebs.iaf(j)-ownbs.iaf(j); end; write(out,"nl",2,"#",12,<: TRAMOS started: name=:>,ownname, "sp",3,"#",12); writecurtime(out); write(out,"nl",1, << -ddd>, "nl",1,<:resource free total:>, "nl",1,<:internals :>,freeinternal,freeinternal+owninternal, "nl",1,<:buffers :>,freebuf,freebuf+ownbuf, "nl",1,<:areas :>,freearea,freearea+ownarea, "nl",1,<:coreblocks :>,noofcoreblocks, "nl",1,<:coreblocksize :>,coreblocksize); write(out,"nl",2,<:bs resources:>, "nl",1,true,11,<:doc:>); write(out,"sp",12,<:temp:>,"sp",12,"sp",12,<:perm:>); write(out,"nl",1,"sp",11); for i:=1,2 do write(out,<:______entry___:>,<:_____segm____:>); write(out,"nl",1,"sp",11); for i:=1 step 1 until 4 do write(out,<:___free__total:>); for i:=1 step 1 until noofbs do begin iaf:=(i-1)*16; laf:=(i-1)*12; write(out,"nl",1,true,11,usercatbs.laf); if -,bs_exist(i) then write(out,<: ** does not exist:>) else for j:=1,2,7,8 do write(out,<< dddddd>, freebs.iaf(j),freebs.iaf(j)+ownbs.iaf(j)); end for bs; outendcur(10); algol list.off; message readcommand program; algol list.on; att:=false add (1 shift 3); attline:=nextsemch; for i:=1 step 1 until noofterminals+1 do begin j:=nextop(8); signalch(attline,j,free); end; for i:=1 step 1 until noofterminals do begin fi:=(i-1)*condescsize; con_desc.fi.con_term_no:=i; condesc.fi.con_ref:=fi; condesc.fi.conaccess:=nextsem; signal(condesc.fi.conaccess); end; ownpda:=owndescr; messaddress:=nextprocext(ownpda); for i:=1 step 1 until maxmess do begin j:=nextcoru(1,100,true); newactivity(j,j,receivemess,i); end mess; for i:=1 step 1 until noofterminals do begin j:=nextcoru(2,100,true); newactivity(j,0,readcommand,i); end; algol list.off; message parent message: program; algol list.on; pmess:=false add (1 shift 4); pmessline:=nextsemch; for i:=1 step 1 until maxpmess do begin j:=nextop(8); signalch(pmessline,j,free); end; j:=nextcoru(3,300,true); newactivity(j,j,receive_parent_message); algol list.off; message error messages program; init_error_text(errortexts); message batch queue: program; algol list.on; setbasestd; tail(1):=swopsegm; laf:=2; for i:=1,2 do tail.laf(i):=swopdoc(i); for i:=6 step 1 until 10 do tail(i):=0; i:=createentry(swop,tail); if i=3 then begin removeentry(swop); i:=createentry(swop,tail); end; if i>0 then alarm(<:***swop area :>,swop,i); permentry(swop,3); resetbase; begin integer cs,cb,blocks; cs:=coreblocksize*512; blocks:=(bmaxsizeday+cs-2)//cs; if blocks<=noofcoreblocks then begin cb:=0; for cb:=1 step 1 until blocks do coretable(cb,2):=ownpda; bchildfirst:=coretable(1,1); bchildlast :=coretable(blocks+1,1)-2; end else begin write(out,"nl",1,<:batch inactive, no free core :>, bmaxsizeday,<: needed:>); bmaxchildren:=0; end; end local; qmess:=false add (1 shift 5); bmess:=false add (1 shift 6); cmess:=false add (1 shift 7); jobtimermess:=false add (1 shift 8); qsem:=nextsem; signal(qsem); qmessline:=nextsemch; for i:=1 step 1 until qdes do begin j:=nextop(12); signalch(qmessline,j,free); end; systime(5,0,timebase); timebase:=timebase/100; day:=(timebase>b_night_to_day and timebase<b_day_to_night); b_max_time:=if day then b_max_time_day else b_max_time_night; bmessline:=nextsemch; for i:=1 step 1 until bmaxchildren do begin bsegmtable(i,1):=0; bsegmtable(i,2):=(i-1)*bmaxsizenight//512; end; for i:=1 step 1 until b_maxjobs+4 do begin j:=nextop(6); signalch(bmessline,j,free); end; for i:=1 step 1 until b_max_jobs do for j:=1 step 1 until 10 do job_table(i,j):=0; setbaseusercat; readbfp(<:newq:>,newqueue,false); i:=lookupentry(qname,tail); if i>0 or tail(1)<=b_max_jobs or newqueue then begin newqueue:=true; tail(1):=b_max_jobs+1; laf:=2; for i:=1,2 do tail.laf(i):=own_disc(i); for i:=7 step 1 until 10 do tail(i):=0; removeentry(qname); i:=createentry(qname,tail); if i>0 then alarm(<:Queue no resources :>,qname,i); end; permentry(qname,3); open(qz,4,qname,1 shift 9); if newqueue then begin outrec6(qz,512); fi:=0; for i:=1 step 1 until 256 do qz.fi(i):=0; qz.fi.q0_max_time_day:=b_max_time_day; qz.fi.q0_max_size_day:=b_max_size_day; qz.fi.q0_max_time_night:=b_max_time_night; qz.fi.q0_max_size_night:=b_max_size_night; qz.fi.q0_night_to_day:=b_night_to_day; qz.fi.q0_day_to_night:=b_day_to_night; qz.fi.q0_upd_time:=b_upd_time:=systime(7,0,0.0); outrec6(qz,512); for i:=1 step 1 until 256 do qz.fi(i):=0; for i:=3 step 1 until b_max_jobs+1 do outrec6(qz,512); setposition(qz,0,0); end newqueue; resetbase; for i:=1 step 1 until qdes do begin fi:=(i-1)*qdescsize; for j:=2 step 1 until qdescsize//2 do q.fi(j):=0; q.fi.conref:=fi; q.fi.conaccess:=nextsem; signal(q.fi.conaccess); end; j:=nextcoru(4,300,true); newactivity(j,j,batch_queue); j:=nextcoru(5,50,true); newactivity(j,j,run_batch); j:=nextcoru(6,25,true); newactivity(j,j,b_timer); j:=nextcoru(7,25,true); newactivity(j,j,run_job_timer); algol list.off; message primary input message: program; algol list.on; setbasestd; primin(1):=long <:primi:> add 'n'; primin(2):=0; createpseudoprocess(primin); primpda:=process_description(primin); priminproc:=nextprocext(primpda); j:=nextcoru(8,40,true); newactivity(j,j,receive_input_message); algol list.off; message automatic upstart: program; <*start up processes*> algol list.on; setbaseusercat; name(1):=long <:osaut:>; name(2):=0; i:=lookup_entry(name,tail); if i=0 and tail(1)>0 then begin <*start up area present*> zone start(128,1,stderror); open(start,4,<:osaut:>,0); i:=nextfreeterm(sysconpda); write(out,"nl",1,<:start up area present:>); outendcur(0); readcommandlist(start,condesc.curcondesc,true); end else lock:=false; resetbase; write(out,"nl",1,<:ready:>,"nl",1); outendcur(10); if fpout then closeout; algol list.off; if simref <> firstsem then initerror(1, false); if semref <> firstop - 4 then initerror(2, false); if coruref <> firstsim then initerror(3, false); if opref <> optop + 6 then initerror(4, false); if proccount <> maxprocext -1 then initerror(5, false); goto takeexternal; dump: end; end ▶EOF◀