.TITLE KNL_SECT_OPEN OPEN AND MAP SECTION FILE IN KERNAL MODE .IDENT /2.A/ ;.begin.doc ************************** begin.doc ; ; .c ;MODULE ; .c ;^&KNL_SECT_OPEN\& ; .nf ; .x KNL_SECT_OPEN>Defined ; Source:KNL_SECT_OPEN.MOD ; Designer :EARL LAKIA ; Author :EARL LAKIA ; Date of last update: 14-OCT-1988 ; Revision level :2.A ; ; .C ;Formal Parameter List ; Receives: ; ; SECTION_NAME CHARACTER ; NAME OF THE SECTION TO CREATE ; ; FAB STRUCTURE ; FAB THAT WAS CALLED FROM THE USER OPEN. ; ; RAB STRUCTURE ; RAB OF FILE THAT WAS CALLED FROM USER OPEN. ; ; LUN INTEGER*4 ; UNIT NUMBER FOR FILE BEING OPENNED. ; ; ; Returns: ; ; Accesses common(s): ; ; .X KDATA>Common ; KDATA STORE CHANNEL NUMBER, ETC. FOR OTHER NON KERNAL ; CODE. ; ; Accesses file(s): ; ; Other modules referenced: ; .SK ; .X OPR_FAO_MSG>Referenced ; OPR_FAO_MSG Log error to OPA0: ; (Found in library: INLAND) ; ; .fill ; .SK ; Description: ; .sk ; .FILL ; This subroutine opens the queue section file for ; Kernal mode access, and stores this processes ; wakeup local event flag and IPID into the global ; queue section so other processes can request a checkpoint. ; An exit handler is set up such that ; when the process exits and approiate words in the section file ; can also be cleared (Don't want processes requesting checkpoint ; by a nolonger existant process). Finally, set up the exclusive update lock ; for the region in null mode state. ; ; This subroutine is called because of a FORTRAN user open. This ; subroutine is passed the following: ; .NOFILL ; (AP)= number of arguments ; 4(AP)= address of the FAB ; 8(AP)= address of the RAB ; 12(AP)= address of a longword containing the unit number ; .FILL ; end.doc ****************************** end.doc ; ; DEBUG FLAG, SETTING WILL ENABLE PRINTING OF DEBUG MESSAGES ; ; DEBUG=1 ; ; ; VERSION: 2.4 ; E. LAKIA. LOCK ID TO THE QUEUE HEADER ; VERSION: 2.6 ; E. LAKIA Get the lock however from the parameter file, passed ; via the common from the Queue_chkr main line code. ; VERSION: 2.8 ; E. LAKIA To ensure that we don't get two queue checker ; processes and also incompatible queues. ; ; VERSION: 2.9 ; E. LAKIA On a restart, clear the number of processes currently ; inside the queue (qhd$l_insrv). ; ; VERSION: 2.A ; E. LAKIA (IPACT)- Remove referecne for SCH$$GL_CURPCB not ; defined for 5.0 of VMS ; ; .LIBRARY /SYS$LIBRARY:LIB/ $IPLDEF $PRIDEF $PRTDEF $SECDEF $CCBDEF $PSLDEF $PCBDEF $ACBDEF $DYNDEF $LCKDEF $LKBDEF $LNMDEF .LIBRARY /MA_Q:[DEF]QUEUE.MLB/ .LIST ME QHDDEF MIDDEF .NLIST ME .page ; ; COMMON USED BY THE QUEUE CHECKER MAIN LINE CODE, ; THE AST ROUTINE AND THE EXIT HANDLER ; ; .PSECT KDATA PIC,GBL,SHR,NOEXE,OVR,LONG SEC_CHAN: .LONG 0 ; SECTION CHANNEL SEC_ADDR: .LONG 0,0 ; RETURNED SECTION MAPPED ADDRESS SEC_NAME: .LONG 0,0 ; SECTION NAME DESCRIPTOR (FILLED IN BY MAIN) LCK_NAME: .LONG 0,0 ; LOCK TO BE ASSOCIATED WITH THE SECTION PAG_CNT: .LONG 0 ; NUMBER OF PAGES IN SECTION (FILLED IN BY MAIN) KNL_STATUS: .LONG 0 ; KERNAL STATUS RETURN KNL_INDEX: .LONG 0 ; KERNAL INDEX (HOW FAR INTO OPEN AND MAP) UPD_ADDR: .LONG 0,0 ; ACTUAL UPDATE SECTION V. A. UPD_EFN: .LONG 0 ; UPDATE SECTION EVENT FLAG WAKE_EFN: .LONG 0 ; WAKE MAINLINE EVENT FLAG IOSTATL: .LONG 0,0 ; I/O STATUS FROM UPDATE MSGDESC: .LONG 0,0 ; MESSAGE DESCRIPTOR MSGBUF: .BYTE 0[250] ; ACTUAL MESSAGE ; ; EXIT HANDLER BLOCK ; .PSECT TEMPS PIC,SHR,NOEXE,CON,LONG DESBLK: .LONG 0 ; FORWARD LINK .ADDRESS KNL_EXIT ; EXIT ROUTINE ADDRESS .LONG 2 ; NUMBER OF ARGUMENTS .ADDRESS EXT_STS ; WILL CONTAIN THE ADDRESS OF THE EXIT REASON .LONG 0 ; VIRTUAL ADDRESS OF REGION (COPIED HERE) ; EVEN THOUGH IN COMMON TOO. EXT_STS: .LONG 0 ; ; LOCK VALUE BLOCK ; LKSB: .QUAD 0 ; LOCK STATUS BLOCK .BLKB 16 ; LOCK VALUE BLOCK ; ; ITEMS LIST, ETC. FOR GETTING OUR NODE NAME (SYS$NODE) ; ITMLST: .WORD 4 ; 4 BYTES FOR INDEX .WORD LNM$_INDEX ; WHAT WE WANT .ADDRESS LNMIDX ; WHERE TO PUT INDEX .LONG 0 ; TERMINATOR ; .WORD 8 ; EIGHT BYTES IN NODE NAME .WORD LNM$_STRING ; WANT EQUIVALENCE STRING .ADDRESS OURNODE ; OUR NODE .LONG 0 ; TERMINATOR LNMIDX: .LONG 0 ; LOGICAL NAME ADDRESS OURNODE: .BYTE 0[8] ; BUFFER FOR NODE NAME EQUIVALENCE STRING NODE: .ASCID /SYS$NODE/ TABLE: .ASCID /LNM$SYSTEM_TABLE/ ATTR: .LONG LNM$M_CASE_BLIND .PAGE ; ; KERNAL SECTION OPEN ; .PSECT KNL_SECT_OPEN,PIC,EXE,CON,LONG,NOWRT .ENTRY KNL_SECT_OPEN,^M ; ; FIRST THING IS TO GET OUR NODE NAME ; .LIST ME $TRNLNM_S ATTR=ATTR,- TABNAM=TABLE,- LOGNAM=NODE,- ITMLST=ITMLST .NLIST ME BLBS R0,5$ ; WAS IT SUCCESSFUL? MOVL R0,KNL_STATUS ; SAVE R0 SO CAN RETURN TO MAINLINE MOVL #250,MSGDESC ; ALWAYS RESET DESCRIPTOR SIZE $GETMSG_S MSGID=R0,- MSGLEN=MSGDESC,- BUFADR=MSGDESC ; PUSHAL MSGDESC ; DECODED ERROR CODE PUSHAL QCK_NODENAME ; QUEUE CHECKER ERROR MESSAGE CALLS #2,OPR_FAO_MSG ; LOG THE MESSAGE 5$: ; ; SET UP THE FAB for contingous, etc. ; MOVL #1,KNL_INDEX ; INDICATE WE GOT HERE MOVL 4(AP),R2 ; GET FAB ADDRESS $FAB_STORE FAB=R2,FOP=,SHR= ; ; CREATE THE FILE ; $CREATE FAB=R2 ; OPEN FILE, NEW BLBS R0,10$ ; ERROR ? JUMP IF OK MOVL R0,KNL_STATUS RET ; YES, RETURN ; ; STORE THE CHANNEL NUMBER IN THE COMMON ; 10$: MOVL #2,KNL_INDEX MOVZWL FAB$L_STV(R2),SEC_CHAN MOVL #SS$_NORMAL,R0 ; RETURN GOOD STATUS MOVL R0,KNL_STATUS MOVL FAB$L_ALQ(R2),PAG_CNT ; NUMBER PAGES= NUMBER ALLOCATED IN FILE ; WHICH MAY BE OVERWRITTEN BY OPEN ; ; OPEN OF THE FILE WAS OK, NOW MAP AND CREATE THE ; SECTION FILE IN KERNAL MODE. ; $CMKRNL_S ROUTIN=MAPSECT MOVL R0,KNL_STATUS BLBS R0,SETEXIT ; WAS STATUS OK?, JUMP IF YES RET ; R0= STATUS OF THE MAP SECTION .PAGE ; ; ACTUALLY DECLARE THE EXIT HANDLER ; SETEXIT: $DCLEXH_S DESBLK=DESBLK ; SET UP EXIT HANDLER BLBS R0,50$ ; ERROR ? JUMP IF OK ; ; UNABLE TO SETUP EXIT HANDLER, THEN CHANGE MODE TO KERNAL ; AND MAKE IT SO NOONE CAN POST AN EVENT FLAG TO A NONEXISTANT ; PROCESS ; $CMKRNL_S ROUTIN=20$ ; GO CLEAR POINTERS RET 50$: ; ; Create a null lock on the exclusive update lock ; as specified in the section at QHD$C_LOCK ; $CMKRNL_S ROUTIN=60$ RET 60$: .WORD ^M MOVZWL LCK_NAME,R5 ; Length of the lock name MOVL SEC_ADDR,R6 ; Start of the created section MOVB R5,QHD$C_CLOCK(R6) ; Byte count of counted string MOVL LCK_NAME+4,R7 ; Address of the lock name string MOVC3 R5,(R7),QHD$C_CLOCK+1(R6) ; Copy lock name ; to queue header MOVL SEC_ADDR,R1 ; START OF MAPPED SECTION ; BUILD DESCRIPTOR FOR LOCK NAME PUSHAB QHD$C_CLOCK+1(R1) ; ADDRESS OF LOCK NAME MOVZBL QHD$C_CLOCK(R1),-(SP) ; STORE COUNT MOVL SP,R1 MOVL #6,KNL_INDEX ; POSSIBLE FAILURE $ENQW_S LKMODE=#LCK$K_NLMODE,- ; NULL MODE LOCK LKSB=LKSB,- ; LOCK STATUS BLOCK FLAGS=#LCK$M_SYSTEM,- ; SYSTEM WIDE LOCK ACMODE=#PSL$C_USER,- ; IN USER MODE RESNAM=(R1) MOVL R0,KNL_STATUS CMPL (SP)+,(SP)+ ; POP THE STACK MOVL SEC_ADDR,R1 ; GET START OF MAPPED SECTION MOVL LKSB+4,QHD$L_LKID(R1) ; STORE LOCK ID MOVZWL QHD$L_LKID(R1),R2 ; GET LOCK ID MOVL G^LCK$GL_IDTBL,R4 ; ADDR. OF SYSTEM LOCK ID TABLE MOVL (R4)[R2],R3 ; GET LKB SYSTEM LOCK ID TABLE MOVL R3,QHD$L_LKB(R1) ; STORE LOCK BLOCK IN QUEUE HEADER MOVL LKB$L_RSB(R3),QHD$L_RSB(R1) ; RSB ADDRESS TOO BICL2 #QHD$M_SHUTDOWN,QHD$L_STAT(R1) ; CLEAR SHUTDOWN BIT CLRL QHD$L_INSRV(R1) ; CLEAR INSERVICE COUNTER RET ; ; KERNAL MODE SO CAN CLEAR POINTERS ; 20$: .WORD ^M ; MOVC3 DESTROIES MOVL SEC_ADDR,R1 ; GET REGION ADDRESS AGAIN CLRL QHD$L_IPID(R1) ; CLEAR PID TOO ; WON'T LET ANYONE QUEUE AST TO US ; ANYMORE. CLRL QHD$L_IPID(R1) ; CLEAR PID CLRL QHD$L_PCB(R1) ; CLEAR OUR PCB ADDRESS CLRL QHD$L_EFN(R1) ; OUR WAKE UP EVENT FLAG ; MOVL #SS$_NORMAL,R0 ; GOOD STATUS ALWAYS RET .PAGE ; ; MAP AND CREATE GLOBAL SECTION WITH KERNAL MODE ACCESS ; ; SEC_CHAN= CHANNEL NUMBER ON THE OPEN SECTION FILE ; ;r4= current pcb ; .ENTRY MAPSECT,^M MOVL R4,R7 ; Save pcb ; ; ELEVATE THE ACCESS MODE OF THE CHANNEL CONTROL BLOCK TO KERNAL ; MNEGL SEC_CHAN,R2 ; GET CHANNEL NUMBER MOVAB @CTL$GL_CCBBASE[R2],R1 MOVB #7,CCB$B_AMOD(R1) ; PROMOTE CHANNEL ACCESS IN CCB ; ; CALL CREATE AND MAP SECTION ; FLAG= SEC$M_GBL ; GLOBAL SECTION FLAG= FLAG ! SEC$M_WRT ; WRITE ACCESS FLAG= FLAG ! SEC$M_EXPREG ; MAP FIRST AVAILABLE FLAG=FLAG ! SEC$M_PERM ; PERMENANT FLAG=FLAG ! SEC$M_SYSGBL ; SYSTEM GLOBAL ; MOVL #3,KNL_INDEX $CRMPSC_S INADR=SEC_ADDR- ; WHERE TO START MAP RETADR=SEC_ADDR- ; RETURN V.A. OF WHERE MAPPED ACMODE=#PSL$C_KERNEL- ; ACCESS MODE FLAGS=#FLAG- GSDNAM=SEC_NAME- ; SECTION NAME DESCRIPTOR RELPAG=#0- ; START MAP FIRST BLOCK CHAN=SEC_CHAN- ; CHANNEL PAGCNT=PAG_CNT- ; SIZE OF SECTION VBN=#0- ; MAP FIRST VBN OF FILE PFC=#10 ; PAGE FAULT CLUSTER SIZE BLBS R0,10$ ; GOOD STATUS? MOVL R0,KNL_STATUS ; RETURN STATUS RET ; BAD STATUS, NOT ENOUGH GLOBAL PAGES ; SYSGENNED IN? ; ; GOOD STATUS, BUT MAKE SURE THAT WE CREATED THE REGION AND THAT ; IT WASN'T ALREADY THERE. ; 10$: CMPL #SS$_CREATED,R0 ; WELL DE WE CREATE IT? BEQL 20$ ; YES MOVL #QCK_ALRDYINS,R0 ; NO, THEN DON'T MAP IT. MOVL R0,KNL_STATUS ; SO MAIN LINE CAN FIND IT EASY RET 20$: MOVL #4,KNL_INDEX ; INDEX OF POSSIBLE FUNCTION THAT ; MAY CAUSE ERROR. .PAGE ; ; LOAD THE REGION WITH EVENT FLAG AND OUR IPID ; MOVL SEC_ADDR,R6 ; GET SECTION ADDRESS ; ; MAKE SURE THAT THE QUEUE WAS TAKEN DOWN GRACEFULLY AND THAT ; WE ARE RUNNING COMPATIBLE VERSIONS. ; BITL #QHD$M_SHUTDOWN,QHD$L_STAT(R6) ; WAS QUEUE SHUTDOWN GRACEFFULY? BNEQ 25$ ; YES MOVL #QCK_POSCORUPT,R0 ; RETURN STATUS MOVL R0,KNL_STATUS ; AND DON'T CONTINUE RET 25$: CMPW #QHD$$VERSION,QHD$W_VERSION(R6) ; COMPATIBLE VERSIONS BEQL 30$ ; YES MOVL #QCK_QUEINCOMP,R0 ; INCOMATIBLE VERSION ERROR MOVL R0,KNL_STATUS RET 30$: CLRL QHD$L_INSRV(R6) ; NUMBER OF PROCESSES IN SYS. SRV. MOVL R7,R0 ; GET CURRENT PCB ADDRESS MOVL R0,QHD$L_PCB(R6) ; STORE OUR PCB MOVL PCB$L_PID(R0),QHD$L_IPID(R6) ; SAVE PID IN REGION FOR OTHERS ; TO REQUEST CHECKPOINT MOVL WAKE_EFN,QHD$L_EFN(R6) ; STORE WAKE UP EVENT FLAG ; ; COPY OUR NODE NAME TO REGION ; MOVL #6,R1 ; NUMBER OF BYTES IN NODE NAME MOVC3 R1,OURNODE,QHD$C_NODE(R6) ; WHERE TO MOVE NODE NAME TO ; ; SET UP AN EXIT HANDLER IN THE EVENT WE EXIT. THIS WILL ; ALLOW FOR CLEANUP, SUCH AS CLEARING AREAS IN THE REGION ; IN ACCESS MODES OTHER THAN KERNAL, THEREFORE, THE ; ACTUAL SETTING WILL BE DONE IN USER MODE. ; MOVL SEC_ADDR,DESBLK+16 ; COPY SECTION ADDRESS TO EXIT BLOCK MOVL R0,KNL_STATUS ; SAVE KERNAL STATUS .PAGE ; ; CLEAR ANY ATTACHED OR CONNECTED PROCESSES FOR ANY MESSAGE ; ID. ; MOVL SEC_ADDR,R0 ; GET SECTION ADDRESS AGAIN MOVL QHD$L_AID(R0),R1 ; NUMBER OF MESSAGE ID'S ALLOCATED ADDL #QHD$K_SIZ,R0 ; POINT TO START OF MESSAGE ID LIST HEADS 40$: CLRW MID$W_EFN(R0) ; CLEAR EVENT FLAG CLRL MID$L_PCB(R0) ; PCB ADDRESS CLRL MID$L_IPID(R0) ; INTERNAL PID CLRL MID$L_CPID(R0) ; CONVENTIONAL PID ADDL #MID$K_LEN,R0 ; POINT TO NEXT MESSAGE ID LIST HEAD SOBGTR R1,40$ ; LOOP UNTIL ALL ARE RESET MOVL #SS$_NORMAL,R0 ; GOOD STATUS RET .PAGE ;.begin.doc ************************** begin.doc ; ; .c ;MODULE ; .c ;^&UPDATE\& ; .nf ; .x UPDATE>Defined ; Source:UPDATE.MOD ; Designer :EARL LAKIA ; Author :EARL LAKIA ; Inland Steel ; Process Automation Department ; 3210 Watling St. MS 2-465 ; East Chicago, IN 46312 ; ; Date of last update:12-AUG-1986 06:36:43.24 ; Revision level :1.0 ; ; .C ;Formal Parameter List ; Receives: ; ; nothing, all parameters are passed by common ; ; Returns: ; ; UPDATE INTEGER*4 ; Status from the Update section call ; ; Accesses common(s): ; ; .X KDATA>Common ; KDATA COMMON USED TO SAVE SECTION ADDRESSES, ETC. ; ; Accesses file(s): ; ; Other modules referenced: ; ; .X OPR_FAO_MSG>Referenced ; OPR_FAO_MSG LOG MESSAGES TO CONSOLE ; (found in library:INLAND) ; .SK ; .fill ; .SK ; Description: ; .sk ; This subroutine is called by the main line (QUEUE_CHKR) ; and used to checkpoint the queue region to the section disk file. ; The subroutine simply changes mode to Kernel (section is ; only mapped in kernel) and does an update section system service. ; The calling sequence is: ; STATUS= UPDATE() ; Any errors are from the update section system service. ; ; end.doc ****************************** end.doc ; ; THIS ROUTINE IS EXECUTED IN USER MODE, THEREFORE, ; MUST CHANGE MODE TO KERNAL AND UPDATE THE SECTION ; .ENTRY UPDATE,^M $CMKRNL_S ROUTIN=3$ MOVL R0,KNL_STATUS ; SAVE STATUS BLBC R0,40$ ; SOMEKIND OF ERROR ; ; GOOD STATUS ; ; DEBUG ; 30$: MOVL #16,KNL_INDEX MOVL R0,KNL_STATUS .IF DF,DEBUG PUSHL UPD_ADDR+4 ; LAST UPDATED ADDRESS PUSHAL QCK_CHECK CALLS #4,OPR_FAO_MSG ; LOG EVENT .ENDC RET ; ; ERROR WHILE CHECKPOINTING ; 40$: PUSHL R0 ; SAVE R0 SO CAN RETURN TO MAINLINE MOVL #250,MSGDESC ; ALWAYS RESET DESCRIPTOR SIZE $GETMSG_S MSGID=R0,- MSGLEN=MSGDESC,- BUFADR=MSGDESC ; PUSHAL MSGDESC ; DECODED ERROR CODE PUSHL KNL_INDEX ; INDEX OF ERROR PUSHAL QCK_UPDERR ; QUEUE CHECKER ERROR MESSAGE CALLS #3,OPR_FAO_MSG ; LOG THE MESSAGE POPR R0 ; RESTORE SAVED STATUS RET ; ; KERNAL MODE ; 3$: .WORD ^M<> MOVL SEC_ADDR,R1 ; GET SECTION ADDRESS MOVL #9,KNL_INDEX ; INDEX IN CASE OF ERROR $GETTIM_S TIMADR=QHD$Q_UPD(R1) ; GET TIME OF LAST CHECKPOINT BLBS R0,7$ RET 7$: MOVL #10,KNL_INDEX $UPDSEC_S INADR=SEC_ADDR- RETADR=UPD_ADDR- ACMODE=#PSL$C_KERNEL- ; ACCESS MODE UPDFLG=#0- ; WRITE ALL PAGES (SINCE WE DON'T WRITE ANY) EFN=UPD_EFN- ; EVENT FLAG IOSB=IOSTATL ; I/O STATUS BLBS R0,10$ ; WAS SERVICE ACCEPTED? RET ; NO, RETURN ; ; WAIT FOR SECTION UPDATE TO COMPLETE. ; 10$: MOVL #13,KNL_INDEX ; UPDATE POSSIBLE ERROR INDEX $SYNCH_S EFN=UPD_EFN,- IOSB=IOSTATL BLBS R0,15$ ; SYSTEM SERVICE ERROR RET ; YES, RETURN 15$: MOVL #14,KNL_INDEX ; UPDATE POSSIBLE ERROR INDEX ; ; Check if the queue is being shut down, if so, then we ; should simply exit. ; MOVL SEC_ADDR,R1 ; GET SECTION ADDRESS BITL #QHD$M_SHUTDOWN,QHD$L_STAT(R1) ; being shut down? BEQL 20$ ; NO $EXIT_S CODE=#QUE_SHUTDOWN ; STATUS CODE 20$: MOVZWL IOSTATL,R0 ; GET ERROR CODE RET ; NOPE, RETURN .PAGE ; ; USER MODE EXIT HANDLER, CHANGE TO ; LOG THE FACTS, THEN CHANGE MODE TO ; KERNAL AND CLEAN UP. ; ; LOG THE FACT THAT WE ARE EXITING, ; DEALLOCATE THE ACB (MUST MARK IT AS NON PERMENANT FIRST), ; CLEAR ENTRIES IN THE REGION SO NOONE CAN QUEUE AST'S TO ; US. ; ; ENTRY IS: ; ; 00(AP)= # ARGUMENTS ; 04(AP)= CONDITION CODE WHICH CAUSED EXIT (ADDRESS OF) ; 08(AP)= GLOBAL SECTION ADDRESS ; KNL_EXIT: .WORD ^M ; ENTRY MASK MOVL 8(AP),R3 ; GLOBAL SECTION ADDRESS MOVL @4(AP),R5 ; CONDITION CODE $CMKRNL_S ROUTIN=20$, MOVL #250,MSGDESC ; ALWAYS RESET DESCRIPTOR SIZE $GETMSG_S MSGID=R5,- ; TRANSLATE ERROR CODE TO SYMBOLIC MSGLEN=MSGDESC,- ; MESSAGE BUFADR=MSGDESC ; PUSHAB MSGDESC ; DECODED ERROR CODE PUSHL #QCK_EXIT ; QUEUE CHECKER ERROR MESSAGE CALLS #2,OPR_FAO_MSG ; LOG THE MESSAGE ; RET ; LET REST OF EXIT HANDLER RUN ; ; KERNAL CODE ; R3= GLOBAL SECTION ADDRESS ; R6= ACB ADDRESS ; 20$: .WORD ^M<> ; ENTRY MASK CLRL QHD$L_PID(R3) ; CLEAR PID CLRL QHD$L_IPID(R3) ; CLEAR IPID CLRL QHD$L_PCB(R3) ; CLEAR OUR PCB ADDRESS RET .END