.TITLE LIB_ABS_QUEUES Absolute queue manipulation routines .IDENT /V2.1/ ;++LIBABSQUE.MAR ; ; Facility: ; Fermilab Accelerator Control System (ACNET) General Routine ; ; Abstract: ; This package contains routines to allow High Level Languages access ; to the VAX-11 INSQUE and REMQUE instructions to manipulate absolute ; queues (similar to the LIB$INSQxI and LIB$REMQxI RTL routines that ; manipulate self-relative queues). ; ; Environment: ; Stored in FERMILIB.OLB library, linked into users' programs. ;-- ; ; Author: A. Waller ; Modification History: ; ; V0.0 15-Jul-82 AW Created ; V1.0 19-Sep-82 FJN Editted for addition to FERMILIB routines ; V1.1 15-Apr-83 FJN Changed help text for standardization ; V2.0 24-Oct-84 FJN Modified to work properly with AST and non-AST queue ; accesses ; V2.1 28-Oct-84 FJN Expanded help information ; .PAGE .SUBTITLE Declarations ; ; Include Files: ; ; NONE ; ; Library Macros: ; .NOCROSS $SSDEF ;Define system completion status codes $LIBDEF ;Define RTL completion status codes .CROSS ; ; Local Macros: ; ; NONE ; ; Equated Symbols: ; ; NONE ; ; Program section for code ; .PSECT _LIB_CODE,PIC,USR,CON,REL,LCL,SHR,EXE,NOWRT,RD .SHOW BINARY .PAGE .SUBTITLE LIB_INSQUE insert entry into queue ;+ LIB_INSQUE ; Insert an entry onto an absolute queue using the VAX-11 INSQUE ; instruction. ; ; ret-status.wlc.v = LIB_INSQUE( entry.mqu.ra, pred.ra.r ) ; ; ret-status completion status code for routine, passed by value: ; SS$_NORMAL successful completion. ; LIB$_ONEENTQUE entry is the first in the queue. ; ; entry an array that must be at least 8 bytes long. Any bytes ; following the first 8 bytes may be used for any purpose ; by the calling module (the first 8 bytes are reserved ; for the forward and backward links of the queue). Passed ; by reference. ; ; pred longword containing the absolute address of the current ; queue entry before which the new entry is to be inserted. ; Passed by reference. Queues referenced by two processes ; or by both AST and non-AST code must insert at the head ; or tail only. ; ;2 Header ; An absolute queue is described by a header consisting of two longwords. ; Each entry in the queue also consists of (at least) two longwords which ; contain the forward and backward link pointers of the queue as absolute ; addresses of the predecessor and trailing queue entries. The link ; pointers of the queue header point to the first and last queue entries. ; ; An empty queue consists of just the queue header in which both the ; forward (first longword) and backward (second longword) link pointers ; point to the queue header itself (addresses of the first longword of ; the queue header). ; ; If more than 1 process (or both AST and non-AST level code within a VMS ; process) can perform operations on a queue simultaneously, then ; insertions and removals should only be done at the head or tail of the ; queue. If only a single process and code level can perform operations ; on a queue, then insertions and removals can be made at other than the ; head or tail of the queue. ;2 Examples ; If the queue header has been declared as: ; ; INTEGER*4 header(2) ; ; then an entry may be inserted at the head of the queue by: ; ; LIB_INSQUE(new_entry, header) or ; LIB_INSQUE(new_entry, header(1)) ; ; and at the tail of the queue by either of: ; ; LIB_INSQUE(new_entry, %VAL(header(2))) or ; LIB_INSQUE_TAIL(new_entry, header) ; ; or after an old entry by doing: ; ; LIB_INSQUE(new_entry, old_entry) ; ; where new_entry and old_entry are the arrays themselves. If the ; address of the new queue entry is stored in a longword (entry), ; then to insert onto the head of the queue do: ; ; LIB_INSQUE(%VAL(entry), header(1)) ; ; and so forth. ;- .ENTRY LIB_INSQUE,^M<> INSQUE @4(AP),@8(AP) ;First parameter is new entry's address BRB BOTH_INSQUE ;+ LIB_INSQUE_TAIL ; Insert an entry onto the tail of an absolute queue using the ; VAX-11 INSQUE instruction. ; ; ret-status.wlc.v = LIB_INSQUE_TAIL( entry.mqu.ra, header.mqu.r ) ; ; ret-status completion status code for routine, passed by value: ; SS$_NORMAL successful completion. ; LIB$_ONEENTQUE entry is the first in the queue. ; ; entry an array that must be at least 8 bytes long. Any bytes ; following the first 8 bytes may be used for any purpose ; by the calling module (the first 8 bytes are reserved ; for the forward and backward links of the queue). Passed ; by reference. ; ; header the quadword queue header (an array of two longwords) ; for the absolute queue. Passed by reference. Queues ; referenced by two processes or by AST and non-AST code ; must insert at the head or tail only. ; ; See also LIB_INSQUE. ;- .ENTRY LIB_INSQUE_TAIL,^M<> MOVL 8(AP),R0 ;Get address of queue's header INSQUE @4(AP),@4(R0) ;First parameter is new entry's address ; ; Common code for LIB_INSQUE routines ; BOTH_INSQUE: BEQL ONE_ENT ;Z-flag set if first entry in queue ; ; Return particular status codes depending upon conditions ; SUCCESS: MOVZWL #SS$_NORMAL,R0 ;Success RET ONE_ENT: MOVL #LIB$_ONEENTQUE,R0 ;Success: queue has/had single entry RET EMPTY: MOVL #LIB$_QUEWASEMP,R0 ;Error: queue was empty RET .PAGE .SUBTITLE LIB_REMQUE remove an entry from queue ;+ LIB_REMQUE ; Remove an entry from an absolute queue using the VAX-11 REMQUE ; instruction. ; ; ret-status.wlc.v = LIB_REMQUE( link.mqu.ra, remque-adr.wa.r ) ; ; ret-status completion status code for routine, passed by value: ; SS$_NORMAL successful completion. ; LIB$_ONEENTQUE entry was the last entry in the queue. ; LIB$_QUEWASEMP queue was already empty (remque-adr is ; meaningless). ; ; link longword containing the absolute address of the entry ; to be removed from the queue. Passed by reference. ; Queues referenced by two processes or by both AST and ; and non-AST code must remove from the head or tail only. ; ; remque-adr longword in which the address of the removed entry is ; returned. Passed by reference. ; ;2 Header ; An absolute queue is described by a header consisting of two longwords. ; Each entry in the queue also consists of (at least) two longwords which ; contain the forward and backward link pointers of the queue as absolute ; addresses of the predecessor and trailing queue entries. The link ; pointers of the queue header point to the first and last queue entries. ; ; An empty queue consists of just the queue header in which both the ; forward (first longword) and backward (second longword) link pointers ; point to the queue header itself (addresses of the first longword of ; the queue header). ; ; If more than 1 process (or both AST and non-AST level code within a VMS ; process) can perform operations on a queue simultaneously, then ; insertions and removals should only be done at the head or tail of the ; queue. If only a single process and code level can perform operations ; on a queue, then insertions and removals can be made at other than the ; head or tail of the queue. ;2 Examples ; If the queue header and an entry pointer have been declared as: ; ; INTEGER*4 header(2), entry ; ; then the entry at the head of the queue is removed by: ; ; LIB_REMQUE(header(1), entry) ; ; and the entry at the tail is removed by: ; ; LIB_REMQUE(header(2), entry) ; ; If entry contains the address of a particular entry on the queue, ; then that entry can be removed by: ; ; LIB_REMQUE(entry, entry) ; ;- .ENTRY LIB_REMQUE,^M<> MOVL 4(AP),R0 ;Get address of longword entry pointer REMQUE @(R0),@8(AP) ;Return address of entry in 2nd arg. BVS EMPTY ;Must check V-flag first before Z-flag BEQL ONE_ENT ;Z-flag set if last queue entry removed MOVZWL #SS$_NORMAL,R0 ;Neither set if more than 1 entry RET .PAGE .SUBTITLE LIB_INIT_QHDR initialize an absolute queue header ;+ LIB_INIT_QHDR ; Initialize the queue header of an absolute queue to empty. ; ; CALL LIB_INIT_QHDR( header.mqu.ra ) ; ; header the quadword queue header (an array of two longwords) ; for the absolute queue. Passed by reference. ; ;- .ENTRY LIB_INIT_QHDR,^M<> MOVL 4(AP),R0 ;Get address of queue header itself MOVL R0,(R0) ;Initialize forward queue link MOVL (R0)+,(R0) ;Initialize backward queue link RET .END