Google
 

Trailing-Edge - PDP-10 Archives - BB-D868D-BM - language-sources/qsrmem.mac
There are 28 other files named qsrmem.mac in the archive. Click here to see a list.
	TITLE	QSRMEM -- Memory Manager for QUASAR

;
;
;                COPYRIGHT (c) 1975,1976,1977,1978,1979
;                    DIGITAL EQUIPMENT CORPORATION
;
;     THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY  BE  USED
;     AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
;     AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.   THIS
;     SOFTWARE  OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
;     OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON.  NO  TITLE  TO
;     AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
;     THE INFORMATION  IN  THIS  SOFTWARE  IS  SUBJECT  TO  CHANGE
;     WITHOUT  NOTICE  AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
;     BY DIGITAL EQUIPMENT CORPORATION.
;
;     DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
;     OF  ITS  SOFTWARE  ON  EQUIPMENT  WHICH  IS  NOT SUPPLIED BY
;     DIGITAL.

	SEARCH	QSRMAC,GLXMAC	;PARAMETER FILE

	PROLOGUE(QSRMEM)	;GENERATE THE NECESSARY SYMBOLS
;	Entry points found in QSRMEM

INTERN	M$GFRE	;;Get a cell from the free list for queue 'H'
INTERN	M$PFRE	;Put cell 'AP' back on the free list for queue 'H'
INTERN	M$RFRE	;Remove cell 'AP' from the queue 'H' and return it to the free list
INTERN	M$DLNK	;Remove cell 'AP' from the queue 'H'
INTERN	M$LINK	;Link cell 'AP' into the queue 'H' before entry 'E'
INTERN	M$ELNK	;Link cell 'AP' at the end of the queue 'H'
INTERN	M$FLNK	;Link cell 'AP' at the front of the queue 'H'
INTERN	M$MOVE	;Move cell 'AP' from queue 'H' to queue 'S1'
SUBTTL	Free Space Management Subroutines

;ROUTINE TO GET A FREE CELL FOR A QUEUE
;CALL	H = QUEUE HEADER POINTER
;	PUSHJ	P,M$GFRE
;	  RETURNS AP = CELL ADDRESS

M$GFRE:	PUSHJ	P,SETSIZ		;SET SIZE FOR THIS QUEUE
	PUSHJ	P,M%GMEM		;ALLOCATE THE SPACE
	MOVE	AP,S2			;RETURN ADDRESS IN AP
	$RETT				;AND RETURN

;ROUTINES TO RETURN A CELL TO THE CORRECT FREE LIST
;CALL	AP = CELL ADDRESS (MAY BE DESTROYED)
;	H  = QUEUE HEADER POINTER
;	PUSHJ	P,M$PFRE (M$RFRE IF ENTRY MUST BE DE-LINKED)

M$RFRE:	PUSHJ	P,M$DLNK		;DE-LINK THIS ENTRY BEFORE RETURNING IT
M$PFRE:	PUSHJ	P,SETSIZ		;SET SIZE FOR THIS QUEUE
	MOVE	S2,AP			;COPY CELL ADDRESS
	PJRST	M%RMEM			;EXIT, RETURNNING MEMORY

;ROUTINE TO MOVE A CELL FROM ONE QUEUE TO ANOTHER (PROCESSING TO USE, ETC..)
;CALL	H  = CURRENT QUEUE
;	AP = THE CELL TO MOVE
;	S1 = NEW QUEUE
;	PUSHJ	P,M$MOVE
;RETURNS AP & H UPDATED TO REFLECT NEW CELL

M$MOVE:	PUSHJ	P,.SAVE1		;SAVE P1 FIRST
	PUSH	P,S1			;SAVE NEW HEADER
	PUSHJ	P,M$DLNK		;REMOVE CELL FROM OLD QUEUE
	PUSHJ	P,SETSIZ		;DETERMINE SIZE OF OLD QUEUE
	MOVE	P1,S1			;SAVE SIZE OF OLD QUEUE
	POP	P,H			;NEW HEADER
	PUSHJ	P,SETSIZ		;FIND SIZE OF THIS ONE
	CAME	S1,P1			;MOVING DIFFERENT SIZES
	  $STOP(MDS,MOVING DIFFERENT SIZES)
	LOAD	S1,.QHPAG(H),QH.SCH	;BASE SCHEDULER VECTOR FOR NEW QUEUE
	JUMPE	S1,M$ELNK		;IF NO VECTOR TACK IT TO THE END
	PJRST	SCHLNK(S1)		;LINK IT IN AND RETURN

;SUBROUTINE TO RETURN SIZE OF QUEUE "H" IN S1, WIPES S2

SETSIZ:	LOAD	S1,.QHPAG(H),QH.SIZ	;GET SIZE OF QUEUE ENTRY
	LOAD	S2,.QHTYP(H),QH.IPC	;GET IPCF BIT FROM QUEUE TYPE
	JUMPE	S2,.RETT		;NO,,RETURN
	MOVEI	S2,SPL.SZ		;GET THE SPOOL SIZE
	CAMGE	S2,G$MPS##		;IS IT LARGER THEN MAX IPCF PACKET SIZE ?
	MOVE	S2,G$MPS##		;NO,,USE PACKET SIZE
	ADD	S1,S2			;GET QUEUE LENGTH
	$RETT				;RETURN
;ROUTINES TO LINK AN ENTRY INTO A QUEUE
;CALL	AP = ENTRY TO LINK
;	H  = QUEUE HEADER POINTER
;	E  = SUCCESSOR OF THIS ENTRY (FOR ORDERING IF CALLING M$LINK)
;	PUSHJ	P,M$xxxx
;		WHERE xxxx IS
;			'LINK' TO LINK ENTRY BEFORE 'E'
;			'ELNK' TO LINK AT THE END OF THE QUEUE
;			'FLNK' TO LINK AT THE BEGINNING OF THE QUEUE

M$ELNK:	LOAD	S1,.QHLNK(H),QH.PTL	;FIND THE LAST
	STORE	AP,.QHLNK(H),QH.PTL	;THIS IS NOW THE LAST
	STORE	S1,.QELNK(AP),QE.PTP	;POINT BACK AT THE OLD LAST
	ZERO	.QELNK(AP),QE.PTN	;LAST HAS NO NEXT
	JUMPE	S1,ELNK.1		;JUMP IF THIS IS THE FIRST
	STORE	AP,.QELNK(S1),QE.PTN	;LINK THE OLD LAST TO THIS ONE
	$RETT				;AND RETURN
ELNK.1:	STORE	AP,.QHLNK(H),QH.PTF	;STORE AS FIRST IN QUEUE ALSO
	$RETT				;AND RETURN

M$FLNK:	LOAD	S1,.QHLNK(H),QH.PTF	;FIND THE FIRST
	STORE	AP,.QHLNK(H),QH.PTF	;THIS IS NOW THE FIRST
	STORE	S1,.QELNK(AP),QE.PTN	;POINT TO THE OLD FIRST
	ZERO	.QELNK(AP),QE.PTP	;FIRST HAS NO PREVIOUS
	JUMPE	S1,FLNK.1		;JUMP IF THIS IS THE LAST
	STORE	AP,.QELNK(S1),QE.PTP	;LINK THE OLD FIRST BACK TO THIS
	$RETT				;AND RETURN
FLNK.1:	STORE	AP,.QHLNK(H),QH.PTL	;STORE THIS AS LAST IN QUEUE ALSO
	$RETT				;AND RETURN

M$LINK:	JUMPE	E,M$ELNK		;USE THE SPECIAL CASE IF THIS IS TO BE THE LAST
	LOAD	S1,.QELNK(E),QE.PTP	;LOAD SUCCESSORS PREVIOUS
	JUMPE	S1,M$FLNK		;JUMP IF THIS IS TO BE THE FIRST
	STORE	S1,.QELNK(AP),QE.PTP	;THAT IS MY PREVIOUS
	STORE	AP,.QELNK(S1),QE.PTN	;AND I AM ITS NEXT
	STORE	E,.QELNK(AP),QE.PTN	;POINT TO THE SUCESSOR
	STORE	AP,.QELNK(E),QE.PTP	;I AM ITS PREVIOUS
	$RETT				;AND RETURN
;ROUTINE TO DISSOLVE THE LINKS OF AN ENTRY
;NORMALLY CALLED BEFORE THE CALL TO M$PFRE AND IS CALLED BY M$RFRE
;CALL	AP = CELL TO REMOVE
;	H  = QUEUE HEADER POINTER
;	PUSHJ	P,M$DLNK

M$DLNK:	LOAD	S1,.QELNK(AP),QE.PTP	;GET LINKS OF THE ENTRY TO BE REMOVED
	LOAD	S2,.QELNK(AP),QE.PTN	;S1 = PREVIOUS, S2 = SUCCESSOR
	JUMPE	S1,DLNK.1		;JUMP IF REMOVING THE FIRST
	JUMPE	S2,DLNK.3		;JUMP IF REMOVING THE LAST
	STORE	S1,.QELNK(S2),QE.PTP	;LINK THE REMAINING ENTRIES TOGETHER
	STORE	S2,.QELNK(S1),QE.PTN	;TO COMPLETELY DISSOLVE THE OLD LINKS
	$RETT				;AND RETURN
DLNK.1:	JUMPE	S2,DLNK.2		;JUMP IF REMOVING THE ONLY
	STORE	S2,.QHLNK(H),QH.PTF	;STORE SUCCESSOR AS THE NEW FIRST
	ZERO	.QELNK(S2),QE.PTP	;AND CLEAR ITS BACKWARD LINK
	$RETT				;AND RETURN
DLNK.2:	ZERO	.QHLNK(H)		;IF REMOVING THE ONLY, CLEAR THE HEADER
	$RETT				;AND RETURN
DLNK.3:	STORE	S1,.QHLNK(H),QH.PTL	;STORE PREVIOUS AS NEW LAST
	ZERO	.QELNK(S1),QE.PTN	;AND CLEAR ITS FORWARD LINK
	$RETT				;AND RETURN


	END