|
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: 17664 (0x4500) Types: TextFileVerbose Names: »tsvchjob«
└─⟦a41ae585a⟧ Bits:30001842 SW-save af projekt 1000, Alarm-system └─⟦72244f0ef⟧ └─⟦this⟧ »tsvchjob«
job jg 5 200 time 11 0 area 9 size 117248 perm disc1 1000 2 ( source = copy 25.1 tsvchlst = set 1 disc1 tsvchlst = indent source mark lc listc = cross tsvchlst o errors head 1 message tsvch program pascal80 spacing.1024 codesize.1024 alarmenv source o c lookup pass6code if ok.yes ( tsvchbin=set 1 disc1 tsvchbin=move pass6code scope user tsvchbin ) tsvchlst = copy listc errors scope user tsvchlst convert errors finis ) \f process vc_handler( opsem : sempointer; var dc_addr : !alarmnetaddr; var sem : !ts_pointer_vector ); const version = "vers 3.01 /"; (* ------------ *) \f (* INTRODUCTION TO THE VC-HANDLER: Abbreviation list for the VC-HANDLER prosess: ( the introduction of the alarmenvironment has made some inconsistenses in the list ) --------------------------------------------- adr address at alarm terminal atc at-connector ath at-handler buf buffer dc district center del delete elm element in input incar incarnation ins insert mac macro address max greatest mes message mic micro address min smallest nb number pvc primary vc rec receiver sem semaphore sen sender sup ts-supervisor vc alarm center vcc vc-connector vct vc-table \f Pseudo-code for the VC-HANDLER process: -------------------------------------- ( this pseudo_code will be updated regularly - last time was 81.02.06 ) PROCESS vc_handler("process_parameters"); CONST . "process_constants, installation dependent" (may be moved to alarm-environment); TYPE . "message_format" (may be moved to alarm-environment); VAR . "vc_table, binary search"; . "addressing_data"; . "scheduling_data"; . "supervising_data"; . "vcc_incarnation_data"; . "error_handling_data"; . "input_semaphore"; . "wait_buffer_semaphore"; BEGIN . "initialization"; . REPEAT . "wait a message on the input_semaphore, and . "handle the message in the buffer, corresponding to the . operation_code, and produce resulting messages"; . "for each resulting message do addressing/indexing . do supervising and signal each of the buffers to the . corresponding input_semaphore"; . until forever END; * of pseudo code * *) \f (*--------------------- process vch help -------------------------------*) process vch_help ( var vcc_inc : vcc_table; (* incarnation table *) var main, (* vch sem *) me, (* vch help sem *) free : !sempointer (* free buffers sem *) ); type note = packed record (* for broadcast *) head : alarmlabel; comp : alarmnetaddr; count : integer end; const write = 2; sleep = 1; tested= 2; down = 4; connection_code = #hc8; helppri = -1; helpsize= 128; var msg, bm : reference; v : vc_range; handler : alarmnetaddr; begin (*------------ main program ----------------*) repeat wait ( msg, me^); if msg^.u4 div 16 = 2 then (* broadcast *) for v:= 1 to vc_l do if vcc_inc(v).state < down then (* send a broadcast *) begin wait ( bm, free^); bm^.u1:= write; bm^.u3:= netc_route; bm^.u4:= msg^.u4; lock bm as buf: note do lock msg as mes: note do begin buf:= mes; buf.head.rec.micro:= vcc_inc(v).vc_mic end; signal ( bm, main^) end else if msg^.u4 = #hc0 then (* note test *) begin lock msg as mes: alarmlabel do handler:= mes.rec; for v:= 1 to vc_l do if vcc_inc(v).state = sleep then begin wait ( bm, free^); bm^.u1:= write; bm^.u3:= netc_route; bm^.u4:= connection_code; lock bm as buf: alarmlabel do with buf do begin no_of_by:= label_size; rec:= handler; rec.micro:= vcc_inc(v).vc_mic; send:= handler; end; signal ( bm, main^); vcc_inc(v).state:= tested; end; end; (* node test *) return ( msg ); until false; end; \f (*--------------------- vch ----------------------------------------*) type alarm_form70 = record (* used in 7.0 *) head : alarmlabel; tail : record vcc_mic : integer; vc_kind : byte; (* 0 means at- and 1 means it-kind *) lam_nb : byte; (* index to the sem array *) port_nb : byte; (* channel number *) end; end; alarm_form74 = record (* format in 7.4 *) head : alarmlabel; vcc_addr : integer end; const ready = 0; (* vcc states *) sleep = 1; tested= 2; down = 4; refuse_code = #h12; (* opcode 1.2 *) \f var (*------------ incar-part ------------*) shad : array ( vc_range) of shadow; vct : vcc_table; (* incarnation table *) (* is used for administration of semaphores and shadow_variables . to all the vcc_incarnations *) vct_index, vct_max : vc_range := 0; (*------------ main-part ------------*) in_mes : reference; who, (* receiver *) here : alarmnetaddr:= alarmnetaddr(macroaddr(0,0,0),vch_mic_addr); result_code : result_range; test : boolean := false; (* true means testmode *) vcc_name : alfa; vcc_nb, alfa_pos : integer; z : zone; shadhelp : shadow; \f (*------------ procedures and functions ------------*) (*------------ externals ------------*) process vcatc( opsem : sempointer; var messem : !ts_pointer; var quesem : !ts_pointer; var vchsem, driversem, timeoutsem, comsem : !sempointer; var dc_address : !macroaddr; micadr : integer; canno : byte ); external; (*------------ forward declaration ------------*) procedure receipt_mes( var rec_mes : reference; result_code : result_range ); forward; procedure refuse ( var msg : reference; cause : result_range); forward; \f (*------------ vct_part ------------*) procedure find_vct_elm( mic : integer; var result : result_range; var index : vc_range ); (*--------------------------------------------------------------- . This procedure returns the index of the element with the given . micro-address. If not found, then the index is that of the . element in front of the place, where it ought to be. . The search strategi is binary search in an ordered list of . elements. The smallest element has the index = 1. . Error - will not appear. ----------------------------------------------------------------*) VAR low, mid, high : vc_range; BEGIN result:= not_found; if vct_max = 0 then index := 0 (* vct is empty *) else (* we first check the lower bound *) if mic < vct(1).vc_mic then index := 0 else if mic = vct(1).vc_mic then begin index:= 1; result:= accepted end else begin (* now the search is started *) low := 1; high := vct_max; (* >1 *) mid := high; repeat with vct(mid) do if mic = vc_mic then begin index := mid; result:= accepted end else if mic < vc_mic then high := mid else low := mid; (* mic > vc_mic *) (* end with *) mid := (high - low) div 2 + low; until (result = accepted) or ( high - low < 2 ); if result <> accepted then index := low; (* mic ought to be placed between low and high *) end (* search-part *); (*q if test then if result = accepted then testout(z,"vct index :",index) else testout(z,"not in vct :",mic); q*) end (* find_vct_el *); \f procedure move_vct_entry ( var rec, from : vc_incar_e ); begin with from do begin rec.vc_mic:= vc_mic; rec.state:= state; rec.in_sem:= in_sem; rec.shix := shix end end; (* of move *) \f procedure place_vct_elm( vcc_mic : integer; result : result_range; var index : vc_range ); (*--------------------------------------------------------------------- . This procedure makes place for an element in the vct, if room for it . and initialize it. . Error => result := rejected. ---------------------------------------------------------------------*) var ix : vc_range; work : vc_incar_e; begin find_vct_elm( vcc_mic, result, index ); if result = accepted then result:= existing_entry else if vct_max >= vc_l then result:= no_room else if (vcc_mic < vc_addr_limit) or (vcc_mic >= at_addr_limit) then begin (*q if test then testout(z,"place_err ",vcc_mic); q*) result:= not_found end else begin (* place the element *) move_vct_entry ( work, vct(vct_max+1)); for ix:= vct_max downto index+1 do move_vct_entry ( vct(ix+1), vct(ix)); vct_max := vct_max + 1; index := index + 1; (* that's the new place *) move_vct_entry ( vct(index), work); vct(index).vc_mic:= vcc_mic; vct(index).state:= sleep; result:= accepted end; end (* place_vct_elm *); \f procedure del_vct_elm( del_mic : integer; var result : result_range ); (*----------------------------------------------------------------------- . This procedure delets an element in the vct, if found. . Error => dc -----------------------------------------------------------------------*) var res : result_range; index, ix : vc_range; work : vc_incar_e; begin find_vct_elm(del_mic, res, index); if res = accepted then begin if not nil ( shad(vct(index).shix)) then begin vct(index).state:= down; break ( shad(vct(index).shix), 47); remove ( shad(vct(index).shix)); move_vct_entry ( work, vct(index)); for ix := index to vct_max - 1 do move_vct_entry ( vct(ix), vct(ix+1)); move_vct_entry ( vct(vct_max), work); vct_max := vct_max - 1; end else end; result:= res end (* del_vct_elm *); \f (*------------ sup-part ------------*) (*------------------------------------------------------------------- . this part will later include several procedures for handling . this modules supervision of vcc's and tss. . so far - you will meet the comment "supervision", where these . procedures are to be called, . and that takes place immediately after waits, and when signalling. --------------------------------------------------------------------*) \f (*------------ signal-part ------------*) procedure signal_to_vcc( var msg : reference; known_index : vc_range ); (*---------------------------------------------------------------------- . This procedure signals the message to the input_semaphore of the vcc, . and do the supervision. If known_index is zero, this procedure . finds the vct-index itself. . No check on known_index. . Error => send receipt_mes. -----------------------------------------------------------------------*) var result : result_range; wanted : integer; index : vc_range; begin lock msg as head : alarmlabel do wanted:= head.rec.micro; if known_index <> 0 then (* check *) if vct(known_index).vc_mic <> wanted then known_index:= 0; if known_index = 0 then find_vct_elm( wanted, result, index ) else index := known_index; if vct(index).state = down then result:= not_ready; if result = accepted then begin signal ( msg, sem( vct(index).in_sem).s^ ); (* supervision - here we need the index for identification of the vcc *) end else begin (*-- reject --*) refuse ( msg, result ); (*q if test then testout(z,"sgnl_vct_err",index); q*) end; end (* signal_to_vcc *); \f procedure receipt_mes ( var rec_mes : reference; result_code : result_range ); (*------------------------------------------------------------------ . This procedure signals receipt-messages to the sup with the . correct u3, u4, address, no_of_by, and result_code. --------------------------------------------------------------------*) begin with rec_mes^ do begin lock rec_mes as head : alarmlabel do with head do begin rec := send; send:= here; result := result_code; end (* lock - with *); u3:= vca_route; u4:= (u4 div 2)*2 + 1; end (* with *); signal( rec_mes, sem(tssup_sem_no).s^ ); end (* receipt_mes *); \f procedure refuse ( var msg : reference; (* message to refused *) cause : result_range (* result code *) ); (* send 1.2 back to sender *) type flawshape = packed record (* for 1.2 *) head : alarmlabel; data : alarmlabel end; 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:= 2*label_size; rec:= send; send:= here; result:= cause; end end; msg^.u3:= vci_route; msg^.u4:= refuse_code; signal ( msg, sem(tssup_sem_no).s^) end; \f begin (*------------ main program ------------*) (*------------ initialisation ------------*) testopen ( z, own.incname, opsem); testout(z,version,al_env_version); if link ("vcatc ", vcatc) <> 0 then testout ( z,"vcclinkerror", 77); for vct_index:= 1 to vc_l do with vct(vct_index) do begin vc_mic:= at_addr_limit; state:= down; in_sem:= vcatc_sem_no - 2 + 2 * vct_index; shix:= vct_index end; (*------------ main repeat_loop-part ------------*) repeat (* until terminate situation *) result_code:= accepted; (*q if test then testout(z,"wait in_sem ",0); q*) wait( in_mes, sem( vch_sem_no ).w^ ); (* here it waits effectively, if no messages has been scheduled *) (* if test then testout(z,"in_mes u3:",in_mes^.u3); if test then testout(z," u4:",in_mes^.u4); *) (* first of all we group the messages, depending on from where it . does come. *) (*q if test then testout(z,"case u3:",in_mes^.u3); if test then testout(z," u4:",in_mes^.u4); q*) case in_mes^.u3 of dummy_route : return ( in_mes ); \f <* timer not used tim_route, tim_route1 (* from timeout *) : begin (*q if test then testout(z,"from timeout",0); q*) (* case on opcode *) receipt_mes( in_mes, rejected ); (* ?????? *) end (* from timeout *); *> \f vci_route, vci_route1, vca_route, vca_route1 (* from a vcc - of kind at *) : begin (* signal to sup *) (* No check here. But this block is planned used, when . the following opcodes are met: . . 0.2 3.1 3.2 3.4 3.5 4.0 8.1 8.3 8.4 9.1 10.3 10.5 . 1.2 . *) (*q if test then testout(z,"from a vcc ",0); q*) (* supervision *) lock in_mes as head : alarmlabel do with head do begin who:= rec; find_vct_elm ( send.micro, result_code, vct_index); end; with vct(vct_index) do if state < down then state:= ready; if who = here then (* for me *) begin return ( in_mes); end else signal(in_mes,sem( tssup_sem_no).s^); end (* from a vcc *); \f netc_route1: (* to vch itself *) begin (*q if test then testout(z,"to vch ",in_mes^.u4); q*) case in_mes^.u4 (* operation code *) of (* 1.2 *) #h12 : return ( in_mes); (* 2.x *) #h20..#h29, #hc0 : signal ( in_mes, sem(vch_int1).s^); (* 7.0 *) #h70 : begin (* creation of a vcc_incanation *) (*** yet, creation is only allowed for vc's of kind at ***) (*** later we must remember to test on vc_kind ***) lock in_mes as mes : alarm_form70 do with mes do begin (* update vct *) if (head.send <> dc_addr) then begin result_code:= unknown_sender; (*q if test then testout(z,"7.0 bad <> :",head.send.macro.dc_addr); q*) end else place_vct_elm( tail.vcc_mic, result_code, vct_index ); if result_code = accepted then begin here.macro:= head.rec.macro; (* make an unambiguous vcc_name *) vcc_name := "vcatc__ "; vcc_nb := abs( vct_index ); alfa_pos := 7; repeat (*q if test then testout(z,"vcc_nb-part:",vcc_nb); if test then testout(z,"alfa_pos :",alfa_pos); q*) vcc_name( alfa_pos ) := chr( vcc_nb mod 10 + ord( "0" ) ); vcc_nb := vcc_nb div 10; alfa_pos := alfa_pos - 1;; until alfa_pos = 6; (* create and start the vcc_incarnation *) (*q if test then testout(z,"creating vcc",vct_index); q*) result_code := create( vcc_name, vcatc( opsem, sem( vct(vct_index).in_sem), sem( vct(vct_index).in_sem + 1 ), sem( vch_sem_no ).s, (* <<<sem( lam_sem_no + tail.lam_nb ).s, >>> *) sem(vagt_sem_no).s, sem( timeout_sem_no ).s, sem(com_pool).w, dc_addr.macro, tail.vcc_mic, tail.port_nb ), shad(vct( vct_index ).shix), vcc_size); if result_code = accepted then start ( shad(vct(vct_index).shix), vcc_pri) else del_vct_elm( tail.vcc_mic, result_code ); (*q if test then testout(z,"create value",c); q*) end (* if *); end (* lock - with *); end (* creation of a vcc_incarnation *); \f #h74: (* remove a vcc *) begin lock in_mes as mes : alarm_form74 do with mes, head do if send <> dc_addr then result_code:= unknown_sender else del_vct_elm ( vcc_addr, result_code) end; \f (* 12.8 *) #hc8: ; (* 12.14 *) #hce: begin (* state:= down broadcast vcc down *) refuse ( in_mes, not_ready); end otherwise refuse ( in_mes, unknown_opcode) end; (* case *) if not nil ( in_mes) then receipt_mes ( in_mes, result_code); end; (* for vch *) \f netc_route: begin (* for a vcc *) (*q if test then testout ( z, "to a vcc ", in_mes^.u4); q*) vct_index:= 0; signal_to_vcc ( in_mes, vct_index) end (* to a vcc *); \f otherwise (* not implemented - now used for change of testmode *) begin (*q test := not test; if test then testout(z,"starttestout",0); if not test then testout(z,"stop testout",0); q*) refuse ( in_mes, unknown_route) end (* otherwise *); end (* case - upon routings information *); until false (* never stop *) end . (* main program *) (* end of file *) «eof»