|
DataMuseum.dkPresents historical artifacts from the history of: RC3500 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC3500 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 31488 (0x7b00) Types: TextFileVerbose Names: »tssupjob«
└─⟦a41ae585a⟧ Bits:30001842 SW-save af projekt 1000, Alarm-system └─⟦72244f0ef⟧ └─⟦this⟧ »tssupjob«
job hj 3 200 time 11 0 area 10 size 100000 ( message ts supervisor source = copy 25.1 tssuplst = set 1 disc1 tssuplst = indent source mark lc listc = cross tssuplst o errors message ts supervisor pascal80 spacing.1200 codesize.1200 alarmenv fetsaosenv source o c lookup pass6code if ok.yes ( tssupbin = set 1 disc1 tssupbin = move pass6code scope user tssupbin ; if ok.yes ; newjob linktssjob ) tssuplst = copy listc errors scope user tssuplst convert errors finis ) \f (*----------------------------------------------------*) (* *) (* ts supervisor *) (* *) (*----------------------------------------------------*) process tssupervisor ( opsem: sempointer; (* allocator, operator *) var sem : !ts_pointer_vector (* ts semaphores *) ); const version= "vers 3.13 /"; (*---------------------- externals -------------------------------*) process timout ( opsem: sempointer; var tim: !ts_pointer; t, m: integer ); external; <* process tsconnector ( opsem: sempointer; var tss, dc, nc, lam, tim, com : !sempointer; var net, s1, s2, s3, s4: !ts_pointer ); external; *> process at_handler ( opsem: sempointer; var dca, tsa : macroaddr; var sem : !ts_pointer_vector ); external; process vc_handler ( opsem: sempointer; var dca, tsa : macroaddr; var sem : !ts_pointer_vector ); external; process lam ( opsem: sempointer; pu, level: integer; var main_sem: !ts_pointer ); external; \f const maxroute = 12; (* for u3 routing *) type (*----------------- options ------------------------------*) grouptable = array (func_grp) of integer; modulref = ( netc, vch, ath, traffic, nc, dc, tss, dummy, empty ); modulident = array (netc..ath) of byte; modultable = array (modulref) of integer; modulstate = array (modulref) of boolean; modulroute = array (0..maxroute) of modulref; leveltab = array (0..max_lam+1) of byte; const (*-------------- options -------------------------------*) traffic_id = 24; (* for time_out *) nc_ident = 25; dc_ident = 26; microadr = modultable ( netc_mic_addr, vch_mic_addr, ath_mic_addr, traffic_id, nc_ident, dc_ident, 0, 0, 0 ); book_id = modulident(1,2,3); interval = modultable(tss_netc_time,tss_vch_time,tss_ath_time, tss_nc_ltime,tss_nc_stime,tss_dc_stime,-1,-1,-1); from = modulroute(tss,tss,netc,netc,ath,ath,4***vch,3***tss); u3val= modulident(netc_route1, netc_route, netc_route); \f (*-------------------- op codes ---------------------------------*) log_code = #h00; (* 0.0 *) nb_code = #h10; (* 1.0 *) refuse_code= #h12; (* 1.2 *) dc_down = #h20; (* 2.0 *) dc_up = #h21; (* 2.1 *) nc_down = #h22; (* 2.2 *) nc_up = #h23; (* 2.3 *) ts_down = #h24; (* 2.4 *) ts_up = #h25; (* 2.5 *) vc_down = #h26; (* 2.6 *) vc_up = #h27; (* 2.7 *) at_down = #h28; (* 2.8 *) at_up = #h29; (* 2.9 *) newlam_code= #h9c; (* 9.12 *) anslam_code= #h9d; (* 9.13 *) new_addr_code= #hb0; (* 11.0 *) new_ans_code = #hb1; (* 11.1 *) nodetest_code= #hc0; (* 12.0 *) nodeans_code= #hc1; (* 12.1 *) input_code = #hc5; (* 12.5 *) contest_code= #hc8; (* 12.8 *) conansw_code= #hc9; (* 12.9 *) (*---------------------- other constants -------------------------*) maxno = 2*2*2*2; (* 4 bits *) read_clock = 2; write = 2; by_father = 47; (* break parameter *) forever = false; label_length = label_size; (* size in words, length in bytes *) logleng = 2*size_supp -(4+2+label_length); rawleng = 2*size_listen - 2; free_sem_no = com_pool; (* free listen buffers are here *) queue = tssup_int1; done = tssup_int2; supp_sem_no = tssup_int3; (* log buffers *) \f (*------------------------ message formats --------------------------*) type testshape = packed record (* for nodetest *) head: alarmlabel; data: array (1..5) of integer end; flawshape = packed record (* for 1.0 and 1.2 *) head : alarmlabel; data : alarmlabel end; note = packed record (* for broadcast *) head: alarmlabel; component: alarmnetaddr; count: integer end; lammess = packed record (* for new lam *) head: alarmlabel; lam_num, lam_level : integer end; \f (*------------------ variables section ------------------------*) var who, here : alarmnetaddr; (* my own addr updated by 11.00 *) debug : integer:= 1; (* controls testoutput *) cv, (* value of create *) lost, (* num of loast messages *) quelen, (* actual queuelength *) maxqueue, (* max queuelength *) queput, (* number of queings *) nodetest_cnt : integer:=0; (* numb of nodetests send *) running : modulstate := modulstate(4***true, false, false, 3***true); ms1, (* a free buffer *) ms : reference; (* mess arrived *) console : zone; (**debug for output **) (*----------------- for ts modules ----------------------*) no : array (netc..ath) of integer; suppool: pool no_req_supp of array (1..size_supp) of integer; lamname : alfa := "lam00 "; leveltable : leveltab := leveltab((max_lam+2) *** 0); proc_lam : array(0..max_lam) of shadow; proc_timeout, proc_vchan, proc_athan : shadow; (*----------------- for timing ---------------------------*) nc_long, nc_short, (* timeouts from 11.0 *) cnt : integer; netaddr: array (nc..dc) of alarmnetaddr; module: modulref; t_out, (* module timeouts *) t_up : array (netc..dc) of reference; (* book and update *) u_pool: pool no_tss_tim of updates; t_pool: pool no_tss_tim of timers; clockpool: pool 1 of ts_time; (**demo **) clock_msg: reference; (*---------------- end of data section -----------------------*) \f <*q q*> (*------------------------ display -----------------------------*) procedure display ( var msg: reference); (* write contents *) const lastword = 16; type abuf = record w: array(1..lastword) of integer end; var i,m : integer; begin lock msg as buf: abuf do with buf do begin m:= (w(1)+1) div 2; if m<7 then m:= 7; if m>lastword then m:=lastword; for i:= 1 to m do testout ( console," data ", w(i)); end; end; <*q q*> \f (*------------------------ gettime -----------------------------*) function gettime : ts_time; type clock_form = record time: ts_time end; begin signal ( clock_msg, sem(timeout_sem_no).s^); wait ( clock_msg, sem(done).w^); lock clock_msg as buf : clock_form do gettime:= buf.time end; \f (*--------------------- odd ------------------------------------*) function odd ( number: integer ) : boolean; begin odd:= number mod 2 = 1 end; \f (*---------------------- send up ---------------------------*) procedure send_up ( (* signals to net-con *) var msg : reference; (* mess to be send *) operation : byte ); (* op code *) begin msg^.u1:= write; msg^.u3:= tss_route; msg^.u4:= operation; if ( debug mod 16 ) >= 8 then display ( msg); signal ( msg, sem(netc_sem_no).s^ ); end; \f (*------------------------ to queue ------------------------------*) procedure to_queue ( var msg : reference ); begin count ( queput); quelen:= quelen+1; if quelen > maxqueue then maxqueue:= quelen; signal ( msg, sem(queue).s^) end; \f <* -- only used in nc (*---------------------- nodetest --------------------------*) procedure nodetest ( node : modulref ); (* node to be tested *) var try : reference; (* node test message *) begin sensesem ( try, sem(free_sem_no).w^); if not nil ( try) then begin nodetest_cnt:= nodetest_cnt+1; lock try as buf : testshape do begin with buf, head do begin no_of_by:= testlength; rec:= netaddr(node); send:= here; result:= 0; ts_add:= gettime; end; buf.data(1):= nodetest_cnt; end; send_up ( try, nodetest_code); timerupdate ( t_up(node), interval(node), sem(timeout_sem_no).s^, sem(done).w^ ) end end; *> \f (*---------------------- broadcast -------------------------*) procedure broadcast ( (* send a broadcast message *) var msg : reference; (* used for message *) element : alarmnetaddr; (* unit in question *) cnt : integer; (* counter in datapart *) operation: byte; (* op code *) recip : modulref); (* reveiver *) const broadlength = label_length+6; begin lock msg as buf : note do with buf, head do begin no_of_by:= broadlength; if recip = netc then rec:= netaddr(nc) else begin rec:= here; rec.micro:= microadr(recip) end; send:= here; update:= insert_code; result:= accepted; op_code:= operation; ts_add:= gettime; component:= element; count:= cnt end; msg^.u1:= write; if recip = netc then msg^.u3:= tss_route else msg^.u3:= netc_route1; msg^.u4:= operation; signal ( msg, sem(no(recip)).s^ ) (* end *) end; \f (*--------------------- start timeout -------------------------*) procedure start_timeout; begin if nil ( proc_timeout ) then begin cv:= link ("timout ", timout ); cv:= create ( "timout ", timout ( opsem, sem(timeout_sem_no), time_out_unit, timeout_l), proc_timeout, tim_size); if cv = 0 then start ( proc_timeout, tim_pri) else begin testout ( console,"timeoutstart", cv); cv:= unlink ( timout) end end end; \f (*------------------- start lam --------------------------------*) procedure start_lam ( nr, level: byte ); begin if nil ( proc_lam(nr)) then begin lamname(4):= chr ( ord("0") + nr div 10); lamname(5):= chr ( ord("0") + nr mod 10); cv:= create ( lamname, lam ( opsem, pu_no, level, sem(lam_sem_no+nr) ), proc_lam(nr), lam_size); if cv = 0 then begin start ( proc_lam(nr), lam_pri); leveltable(nr):= level end else testout ( console,"lam start ", cv); end; end; \f <*------------------- start netcon ----------------------------* procedure start_netcon; begin if nil ( proc_netcon ) then begin (* cv:= link ("netconnector", netconnector ); *) cv:= link ("tsconnector ", tsconnector); cv:= create ( "tsconnector ", tsconnector ( opsem, sem(tssup_sem_no).s, sem(dc_sem_no).s, sem(nc_sem_no).s, sem(lam_sem_no).s, sem(timeout_sem_no).s, sem(com_pool).w, sem(netc_sem_no), sem(net_int1), sem(net_int2), sem(net_int3), sem(net_int4) ), proc_netcon, netc_size); if cv = 0 then start ( proc_netcon, netc_pri) else begin testout ( console,"netcon start", cv ); cv:= unlink ( tsconnector) end; end end; -------------------------------------------------------------*> \f (*----------------------- start vchandler ---------------------*) procedure start_vchan; begin if nil ( proc_vchan ) then begin cv:= link ( "vc_handler ", vc_handler); cv:= create ( "vc_handler ", vc_handler ( opsem, netaddr(dc).macro, here.macro, sem ), proc_vchan, vch_size); if cv = 0 then start ( proc_vchan, vch_pri) else begin testout ( console, "vc_han start", cv); cv:= unlink ( vc_handler) end end end; \f (*------------------------ start athandler -----------------------*) procedure start_athan; begin if nil ( proc_athan ) then begin cv:= link ( "at_handler ", at_handler); cv:= create ( "at_handler ", at_handler ( opsem, netaddr(dc).macro, here.macro, sem ), proc_athan, ath_size); if cv = 0 then start ( proc_athan, ath_pri ) else begin testout ( console, "at_han start", cv); cv:= unlink ( at_handler ) end end end; \f (*---------------------- module timeout --------------------*) procedure module_timeout ( var msg : reference; (* received mess *) var res : modulref); (* becomes dummy *) var cnt, who : integer; elem : alarmnetaddr; bm1, bm2 : reference; (* 2 empty buffers *) begin sensesem ( bm1, sem(free_sem_no).w^); if not nil ( bm1) then sensesem ( bm2, sem(free_sem_no).w^); if nil ( bm2 ) then begin (* try later *) if not nil ( bm1) then return ( bm1); to_queue ( msg) end else begin lock msg as buf : timers do who:= buf.object; elem.macro:= here.macro; elem.micro:= who; case who of <* netc_mic_addr: begin (* net-connector stopped, so remove it and start a new one *) break ( proc_netcon, by_father); unlink ( tsconnector); remove ( proc_netcon); (* get released buffers. *) start_netcon; nodetest ( nc); timerbook ( t_up(netc), msg, interval(netc), who, sem(timeout_sem_no).s^, sem(done).w^) end; *> ath_mic_addr: begin if running(ath) then begin broadcast ( bm1, elem, 0, at_down, netc); broadcast ( bm2, elem, 0, at_down, vch ) end; running(ath):= false; timerbook ( t_up(ath), msg, -1, who, sem(timeout_sem_no).s^, sem(done).w^) end; vch_mic_addr: begin if running(vch) then begin broadcast ( bm1, elem, 0, vc_down, netc); broadcast ( bm2, elem, 0, vc_down, ath ); running(vch):= false end; timerbook ( t_up(vch), msg, -1, who, sem(timeout_sem_no).s^, sem(done).w^) end; <* traffic_id: begin (* nc or paxnet stopped *) nodetest ( nc); timerbook ( t_up(traffic), msg, -1, who, sem(timeout_sem_no).s^, sem(done).w^) end; *> nc_ident: begin (* nc down *) if running(nc) then begin broadcast ( bm1, elem, 0, nc_down, ath); broadcast ( bm2, elem, 0, nc_down, vch); running(dc):= false; running(nc):= false end; timerbook ( t_up(nc), msg, -1, who, sem(timeout_sem_no).s^, sem(done).w^) end; <* dc_ident: begin (* dc down *) if running(dc) then begin broadcast ( bm1, elem, dc_down, ath); broadcast ( bm2, elem, dc_down, vch); running(dc):= false end; timerbook ( t_up(dc), msg, -1, who, sem(timeout_sem_no).s^, sem(done).w^); end; *> otherwise begin return ( bm1); return ( bm2) end end end; res:= dummy end; (* of module timeout *) \f (*--------------------- route ---------------------------*) function route ( microadr : integer (* addr of local module *) ) : modulref; (* the selected module *) begin if microadr >= at_addr_limit then route:= ath else if microadr >= vc_addr_limit then route:= vch else if microadr = vch_mic_addr then route:= vch else if microadr = ath_mic_addr then route:= ath else if microadr = netc_mic_addr then route:= netc else if microadr = tss_mic_addr then route:= tss else route:= dc end; \f (*----------------------- waitlog ----------------------------------*) procedure waitlog ( (* fetch a free logbuffer *) var msg : reference ); (* a msg for log *) begin (* allocator may be used later ! *) if open ( sem(supp_sem_no).w^) then begin wait ( msg, sem(supp_sem_no).w^ ); while msg^.u3 = dummy_route do begin return ( msg); wait ( msg, sem(supp_sem_no).w^ ) end; end end; \f (*---------------------- make log --------------------------*) procedure make_log ( var msg : reference ); (* makes a copy of msg.data and send to dc. *) type logshape = packed record head : alarmlabel; extra : integer; byno : integer; data : array (1..logleng) of byte; end; rawshape = packed record bytes : integer; rawdata : array (1..rawleng) of byte; end; var cnt : 1..rawleng; length : integer; logm : reference; begin lock msg as head : alarmlabel do head.op_code:= msg^.u4; (* if ( logmin <= msg^.u4) and ( msg^.u4 <= logmax ) then +++++++ begin -------------------------------------------------------*) waitlog ( logm ); if nil ( logm) then to_queue ( msg) else begin if msg^.u4 = refuse_code then (* make copy 1.0 *) begin lock logm as copy: flawshape do lock msg as buf: flawshape do begin copy:= buf; copy.head.rec.macro:= netaddr(dc).macro; copy.head.rec.micro:= dc_erh_mic_addr; end; send_up ( logm, nb_code) end else \f begin (* make log 0.0 *) lock logm as log : logshape do lock msg as buf : rawshape do begin length:= label_length; if ( buf.bytes > label_length ) and ( buf.bytes <= rawleng ) and ( buf.bytes <= logleng ) then length:= buf.bytes; with log, head do begin no_of_by:= label_length+2+length; rec.macro:= netaddr(dc).macro; rec.micro:= dc_log_mic_addr; send:= here; update:= insert_code; ts_add:= gettime; end; log.extra:= quelen; log.byno:= buf.bytes; for cnt:= 1 to length do log.data(cnt):= buf.rawdata(cnt); end; send_up ( logm, log_code) end end (* end --------------------------------------- ++++++++++++++++*) end; \f (*--------------------- refuse --------------------------*) procedure refuse ( var msg : reference; cause : result_range ); (* send opcode 1.2 back *) const newleng = 2*label_length+2; var receiver : macroaddr; who : integer; begin lock msg as buf : flawshape do with buf do begin data:= head; data.op_code:= msg^.u4; with head do begin no_of_by:= newleng; rec:= send; receiver:= rec.macro; who:= rec.micro; send:= here; result:= cause; ts_add:= gettime end end; if receiver <> here.macro then send_up ( msg, refuse_code) else begin if who < vc_addr_limit then msg^.u3:= netc_route1 else msg^.u3:= netc_route; msg^.u4:= refuse_code; case route ( who) of ath: signal ( msg, sem(ath_sem_no).s^); vch: signal ( msg, sem(vch_sem_no).s^); otherwise send_up ( msg, refuse_code) end; end; end; \f (*---------------- downwards ----------------------------*) procedure downwards ( var msg : reference; (* a msg from net *) var modul : modulref); (* tells what to do later *) var receiver : macroaddr; from : alarmnetaddr; xmt_dc : 0..15; who : integer; begin lock msg as head : alarmlabel do with head do begin receiver:= rec.macro; who := rec.micro; xmt_dc := send.macro.dc_addr; from := send; end; if ( debug mod 32 ) >= 16 then display ( msg); if receiver <> here.macro then (* not for me *) if msg^.u4 = refuse_code then modul:= empty else begin refuse ( msg, unknown_receiver); modul:= dummy end else begin (* addr ok *) if (xmt_dc <> here.macro.dc_addr) and running(dc) then make_log ( msg ); if from = netaddr(dc) then running(dc):= true; if nil ( msg) then modul:= dummy else begin modul:= route ( who ); if who < vc_addr_limit then msg^.u3:= netc_route1; end end end; (* of downwards *) \f (*---------------- upwards -------------------------*) procedure upwards ( var msg : reference; (* a msg from ath or vch *) var modul : modulref); (* tells what to do later *) var receiver : macroaddr; who : integer; begin lock msg as head : alarmlabel do begin head.ts_add:= gettime; receiver:= head.rec.macro; who:= head.rec.micro end; if receiver <> netaddr(dc).macro then (* log *) if running(dc) then make_log ( msg ); if nil ( msg) then modul:= dummy else begin if receiver = here.macro then begin modul:= route ( who ); if modul < tss then if who < vc_addr_limit then msg^.u3:= netc_route1 else msg^.u3:= netc_route end else modul:= netc end end; \f (*----------------------- rec broadcast ---------------------------*) procedure rec_broadcast ( var msg : reference ); (* handle received broadcast *) type ncaddr = record dcpart : 0..15; ncpart : 0..63 end; var cnt : integer; unit : alarmnetaddr; own_dc, unit_dc : 0..15; own_nc, unit_nc : ncaddr; bm1, bm2 : reference; begin sensesem ( bm1, sem(free_sem_no).w^); if nil ( bm1) then begin (* try later *) to_queue ( msg) end else begin lock msg as buf: note do with buf do begin unit:= component; cnt := count end; own_dc:= here.macro.dc_addr; own_nc.dcpart:= own_dc; own_nc.ncpart:= here.macro.nc_addr; unit_dc:= unit.macro.dc_addr; unit_nc.dcpart:= unit_dc; unit_nc.ncpart:= unit.macro.nc_addr; case msg^.u4 of dc_down: if unit_dc = own_dc then running(dc):= false; dc_up: if unit_dc = own_dc then running(dc):= true; nc_down: if unit_nc = own_nc then running(nc):= false; nc_up: if unit_nc = own_nc then running(nc):= true otherwise end; case msg^.u3 of netc_route1: begin (* from net *) testout ( console, "from net ", msg^.u3); broadcast ( bm1, unit, cnt, msg^.u4, vch); broadcast ( msg, unit, cnt, msg^.u4, ath) end; at_route, at_route1: begin (* from at *) testout ( console, "from at ", msg^.u3); broadcast ( bm1, unit, cnt, msg^.u4, netc); broadcast ( msg, unit, cnt, msg^.u4, vch) end; vca_route, vca_route1, vci_route, vci_route1: begin (* from vc *) testout ( console, "from vc ", msg^.u3); broadcast ( bm1, unit, cnt, msg^.u4, netc); broadcast ( msg, unit, cnt, msg^.u4, ath) end otherwise begin return ( bm1); return ( msg) end end; (* case *) end end; (* of rec broadcast *) \f (*------------------------ new lam ---------------------------------*) procedure new_lam ( var msg : reference ); (* start or check lam driver incarnation *) const top = max_lam+1; var nr, level : integer; index : 0..top; begin if msg^.u4 = newlam_code then begin (*q if debug >= 1 then testout ( console,"new lam ", msg^.u4); q*) lock msg as buf: lammess do with buf, head do begin result:= rejected; nr:= lam_num; level:= lam_level; index:= 0; while leveltable(index) <> level do index:= index+1; if update = start_code then (* start lam driver *) begin if index = top then start_lam ( nr, level); if leveltable(nr) = level then result:= accepted; end else begin (* stop lam driver *) if leveltable(nr) = level then begin remove ( proc_lam(nr)); leveltable(nr):= 0; result:= accepted end end; rec:= send; send:= here; ts_add:= gettime; end; send_up ( msg, anslam_code) end else refuse ( msg, unknown_opcode) end; \f (*----------------------- rec returned ----------------------------*) procedure rec_returned ( var msg : reference ); (* handle op codes 1.0 1.2 *) begin (* not yet specified *) if debug >= 1 then testout ( console, "returned ", msg^.u4); if debug >= 1 then lock msg as buf: flawshape do with buf do testout ( console, "orig op-code", data.op_code); count ( lost); return ( msg ) end; \f (*----------------------- tss var update ----------------------------*) procedure var_update ( var msg : reference ); (* the buffer contains a new ts-macro-address *) type table = packed record head : alarmlabel; adr : macroaddr; cn: integer end; begin if msg^.u4 = new_addr_code then begin lock msg as buf : table do with buf, head do begin here.macro:= adr; netaddr(dc).macro.dc_addr:= here.macro.dc_addr; netaddr(nc).macro.dc_addr:= here.macro.dc_addr; netaddr(nc).macro.nc_addr:= here.macro.nc_addr; debug:= cn; (* generate answer *) rec:= send; send:= here; ts_add:= gettime; result:= accepted; end; (* if debug>=3 then display ( msg); *) running(dc):= true; running(nc):= true; send_up ( msg, new_ans_code); end else refuse ( msg, unknown_opcode) end; (* of table update *) \f (*----------------------- watch -----------------------------------*) procedure watch ( var msg : reference ); (* nodetest received, so send node test answer *) var node : modulref; node_up : byte; begin if msg^.u4 = nodetest_code then (* node test *) begin lock msg as buf : testshape do with buf, head do begin rec:= send; send:= here; result:= accepted; ts_add:= gettime; nc_long:= data(2); data(2):= quelen; data(3):= queput; data(4):= maxqueue; data(5):= lost; end; send_up ( msg, nodeans_code) end else if msg^.u4 = nodeans_code then (* node test answer *) begin lock msg as buf: testshape do if buf.head.send.macro.nc_addr = 0 then begin node_up:= dc_up; node:= dc end else begin node_up:= nc_up; node:= nc end; timerupdate ( t_up(node), -1, sem(timeout_sem_no).s^, sem(done).w^); if not running(node) then (* node running again *) begin (* broadcast ( ms1, netaddr(node), node_up, ath); broadcast ( msg, netaddr(node), node_up, vch); *) running(node):= true end; return ( msg); end else refuse ( msg, unknown_opcode) end; (* of watch *) \f (*------------------------- tss function --------------------------*) procedure tss_function ( var msg : reference ); (* msg : received message for ts-supervisor *) var group : func_grp; begin (*q if debug>= 3 then testout ( console,"tss gets ", msg^.u4); q*) group:= msg^.u4 div maxno; case group of 0: (* returned log *) begin return ( msg); testout ( console, "log retur ", lost ); end; 1: (* returns *) rec_returned ( msg ); 2: (* broadcast *) rec_broadcast( msg ); 9: (* new lam *) new_lam ( msg ); 11: (* update var *) var_update ( msg); 12: (* watch *) watch ( msg ) otherwise (* refuse *) refuse ( msg, unknown_opcode) end; end; (* of tss function *) \f (*-------------------- exception ---------------------------------*) procedure exception ( cause : integer); begin trace ( cause); if not nil ( ms1) then return ( ms1); if not nil ( ms ) then refuse ( ms, breaked); sensesem ( ms, sem(queue).w^); while not nil ( ms) do begin refuse ( ms, breaked); sensesem ( ms, sem(queue).w^) end; for module:= netc to ath do begin wait ( ms, sem(free_sem_no).w^); broadcast ( ms, here, lost, ts_down, module) end; repeat wait ( ms, sem(tssup_sem_no).w^); if ms^.u4 < #h30 then return ( ms) else refuse ( ms, breaked) until false; end; \f (*---------------------------------------------------------------*) (* *) (* main program *) (* *) (*---------------------------------------------------------------*) begin testopen ( console, own.incname, opsem); if debug>=0 then testout ( console, version, al_env_version); here.macro:= macroaddr(0,0,0); here.micro:= tss_mic_addr; netaddr(dc):= here; netaddr(nc):= here; (**demo get buffers for log and clock **) for cnt:= 1 to no_req_supp do begin alloc ( ms, suppool, sem(supp_sem_no).s^); ms^.u3:= tss_route; signal ( ms, sem(supp_sem_no).s^ ) end; alloc ( clock_msg, clockpool, sem(done).s^); clock_msg^.u1:= read_clock; clock_msg^.u3:= tss_route; no(netc):= netc_sem_no; no( vch):= vch_sem_no; no( ath):= ath_sem_no; cv:= link ("lam ", lam); if cv <> 0 then testout ( console, "link lam = ", cv); start_lam ( 0, 5); start_timeout; \f (*-------- wait for a node-test ------------ *) repeat wait ( ms, sem(tssup_sem_no).w^); case ms^.u3 of netc_route1, dummy_route: return ( ms); netc_route: begin lock ms as head: alarmlabel do cv:= head.rec.micro; if cv = netc_mic_addr then begin ms^.u3:= netc_route1; signal ( ms, sem(netc_sem_no).s^); end else if cv = tss_mic_addr then if (ms^.u4 = new_addr_code) or (ms^.u4 = nodetest_code) then begin lock ms as head: alarmlabel do with head do begin if ms^.u4 = new_addr_code then begin here:= rec; result:= accepted; end else result:= not_ready; who:= rec; rec:= send; send:= who; ts_add:= gettime; end; send_up ( ms, ms^.u4+1); end else refuse ( ms, unknown_opcode) else refuse ( ms, not_ready); end; otherwise send_up ( ms, ms^.u4); end (* case *) until here.macro <> macroaddr(0,0,0); netaddr(dc).macro.dc_addr:= here.macro.dc_addr; netaddr(nc).macro.dc_addr:= here.macro.dc_addr; netaddr(nc).macro.nc_addr:= here.macro.nc_addr; running(dc):= true; running(nc):= true; (*----------- now started -------------*) \f for module:= netc to dc do begin alloc ( t_out(module), t_pool, sem(tssup_sem_no).s^ ); alloc ( t_up(module), u_pool, sem(done).s^); t_up(module)^.u3:= tss_route; timerbook ( t_up(module), t_out(module), -1, microadr(module), sem(timeout_sem_no).s^, sem(done).w^) end; (* start_netcon; done by opsys *) start_vchan; start_athan; (* kun for ts-connector wait ( ms, sem(free_sem_no).w^); lock ms as head: alarmlabel do begin head.rec:= here; head.send:= here; end; send_up ( ms, new_ans_code); *) (*q if debug>=1 then testout ( console,"init ok ", 820 ); q*) \f (*------------------ main loop -------------------------*) repeat (* until forever *) if open ( sem(queue).w^) then sensesem ( ms1, sem(free_sem_no).w^); if open ( sem(queue).w^) and not nil ( ms1) then (* take queue *) begin wait ( ms, sem(queue).w^); quelen:= quelen-1 end else begin (*q if (debug mod 8)>=4 then testout ( console,"wait mysem ", 960 ); q*) wait ( ms, sem(tssup_sem_no).w^ ); end; (*q if (debug mod 8)>=4 then testout ( console,"handle ", msg_ready); q*) case ms^.u3 of dummy_route: module:= empty; tim_route, tim_route1: module_timeout ( ms, module ); netc_route: downwards ( ms, module); netc_route1: begin lock ms as buf: flawshape do if buf.data.rec.macro = netaddr(dc).macro then running(dc):= false; if running(dc) then make_log ( ms); if nil ( ms) then module:= dummy else downwards ( ms, module); end; otherwise upwards ( ms, module ); end; case module of dummy: ; (* no action *) empty: return ( ms ); (* no data *) tss: tss_function ( ms ); vch: signal ( ms, sem(vch_sem_no).s^ ); ath: signal ( ms, sem(ath_sem_no).s^ ); netc: begin if ( debug mod 16 ) >= 8 then display ( ms); signal ( ms, sem(netc_sem_no).s^ ); end otherwise refuse ( ms, not_found) end; (* case *) until forever end . (* of ts supervisor program *) «eof»