Google
 

Trailing-Edge - PDP-10 Archives - BB-R775C-BM - sources/memman.mac
There are 10 other files named memman.mac in the archive. Click here to see a list.
	TITLE	MEMMAN - MEMORY MANAGEMENT ROUTINES


; IDENT 1-004

;****************************************************************************
;*									    *
;*  COPYRIGHT (C) 1978, 1985                                                *
;*  BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.			    *
;*  ALL RIGHTS RESERVED.                                                    *
;* 									    *
;*  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.  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.		    *
;*									    *
;****************************************************************************

;
;FACILITY:	EDT VERSION 3
;

;AUTHOR : GRAHAM BEECH	CREATION DATE : 11-APR-1983

;FUNCTIONAL DESCRIPTION:
;
; 	THIS MODULE CONTAINS ROUTINES TO HANDLE THE ALLOCATION
;	AND DEALLOCATION OF DYNAMIC MEMORY FOR THE WORK FILE
;	AND OTHER SCRATCH AREAS.
;
;MODIFIED BY:
;
; 1-001  Original.  GB 11-Apr-1983
; 1-002  Rewritten using new allocation scheme.  GB 27-Jun-1983
; 1-003  Modify to include DEAMEM - deallocate all memory, so that EDT can
;        be made restartable. CJG 11-Oct-1983
; 1-004  Check that only memory in the legal range is deallocated. CJG 11-Oct-1983
; 1-005  Make BPWORD an external location so that we can change byte size more
;	 easily. CJG 15-Dec-1983
;--

	PAGE

	TWOSEG
	RELOC	0

	SEARCH	MONSYM
	SEARCH	MACSYM

	INTERN	ALLHEA,DEAHEA,ALLPAG,DEAPAG,DEAMEM

	EXTERN	BPWORD

	T1=1
	T2=2
	T3=3
	T4=4
	T5=5
	T6=6
	P=17

	PAGE
	SUBTTL	Local storage

; Free memory is organised into a linked list of noncontiguous
; blocks with FFREE pointing to the first block.
;
; The first word of each block contains the size of the block
; in the left half and a pointer to the next block (or zero)
; in the right half.
;
; When memory is allocated it is allocated from the end of the
; first block which is large enough, and the length is reduced
; by the number of words allocated.
;
; When memory is deallocated it is linked into the list of free
; blocks at the appropriate place (the list is always ordered by
; address). If two blocks can be concatenated into one then
; this is done.

INIT:	BLOCK	1		;Initialised flag
FFREE:	BLOCK	1		;Pointer to first free block
FREPGS:	BLOCK	1		;Number of free pages "allocated"
FFLOW:	BLOCK	1		;First free location
FFHIGH:	EXP	400000		;Last free location + 1 
	PAGE
	SUBTTL	ALLHEA - Allocate heap
	RELOC	400000

;
; ALLOCATE THE REQUESTED NO. OF BYTES OF SCRATCH MEMORY
;
; ARGUMENTS ON STACK :-
;	#BYTES OF MEMORY REQUIRED
;	ADDRESS OF WORD WHICH GETS ADDRESS OF FIRST ALLOCATED WORD
;

ALLHEA::
	SKIPN	INIT			;Memory initalised?
	 CALL	INIMEM			;No. Do it now
	MOVE	T1,@-2(P)		;Get # bytes required
	ADD	T1,BPWORD		;Make it words
	SUBI	T1,1			;...
	IDIV	T1,BPWORD		;...
	MOVEI	T2,FFREE		;Get first free ptr
ALLHE1:	MOVEI	T4,(T2)			;Save previous address
	HRRZ	T2,(T2)			;Get address of next free
	JUMPE	T2,ALLHE8		;Is there one?
	HLRZ	T3,(T2)			;Get length of this block
	CAIGE	T3,(T1)			;Big enough?
	 JRST	ALLHE1			;No - try for another
	SUBI	T3,(T1)			;Reduce its size
	JUMPN	T3,ALLHE4		;Any left?
	HRRZI	T3,(T2)			;No - unlink it from the chain
	HRRM	T3,(T4)			;....

ALLHE4:	HRLM	T3,(T2)			;Store new size
	ADDI	T2,(T3)			;Get address of allocated memory
	MOVEM	T2,@-1(P)		;...and return it
	MOVEI	T1,1			;Success.
	RET

ALLHE8:	SETZ	T1,			;Return failure
	RET

	PAGE
	SUBTTL DEAHEA - Deallocate heap

; DEALLOCATE HEAP STORAGE
;
; ARGUMENTS ON STACK:-
;	# BYTES BEING RELEASED
;	ADDRESS OF FIRST WORD TO BE RELEASED
;
DEAHEA::
	MOVE	T2,@-2(P)		;Get # bytes
	ADD	T2,BPWORD		;Convert to words
	SUBI	T2,1			;...
	IDIV	T2,BPWORD		;...
DEAHE0:	MOVE	T1,@-1(P)		;Get address
	CAML	T1,FFLOW		;If too low ..
	 CAML	T1,FFHIGH		;Or too high ..
	  RET				;Then ignore it
	MOVEI	T3,FFREE		;Get first free
DEAHE1:	MOVEI	T4,(T3)			;Remember previous
	HRRZ	T3,(T3)			;..and get next
	JUMPE	T3,DEAHE2		;Is there one?
	CAIG	T3,(T1)			;Find address > block
	 JRST	DEAHE1			;...we are releasing
DEAHE2:	HLRZ	T5,(T4)			;Get length of previous
	ADDI	T5,(T4)			;See if we can concatenate
	CAIN	T5,(T1)			;...with previous block
	 JRST	DEAHE3			;Yes. Just need to change length
	HRRM	T1,(T4)			;No. Link the block
	HRRM	T3,(T1)			;..into the chain.
	HRLM	T2,(T1)			;...
	RET

DEAHE3:	HLRZ	T5,(T4)			;Get the length
	ADDI	T5,(T2)			;Add length of block being released
	MOVEI	T1,(T5)			;Copy new length
	ADDI	T1,(T4)			;Add address of this block
	CAIE	T1,(T3)			;Combine with next?
	 JRST	DEAHE4			;No.
	HLRZ	T1,(T3)			;Yes. get length of next
	ADDI	T5,(T1)			;Total length
	HRRZ	T1,(T3)			;Forward pointer
	HRRM	T1,(T4)			;Update link
DEAHE4:	HRLM	T5,(T4)			;Update length
	RET

	PAGE
	SUBTTL	ALLPAG - Allocate pages

; ALLOCATE PAGES OF FREE MEMORY
;
; ARGUMENTS ON STACK :-
;	#PAGES REQUIRED
;	ADDRESS OF WORD WHICH GETS ADDRESS OF FIRST ALLOCATED PAGE
;

ALLPAG::
	SKIPN	INIT			;Memory initalised?
	 CALL	INIMEM			;No. Do it now
	MOVE	T1,@-2(P)		;Get # pages required
	IMULI	T1,^D512		;Make it words
	MOVE	T2,FFREE		;Get first free ptr
	TLNE	T2,777			;Check its a page boundary
	 JRST	ALLPA9			;This should never happen!!
	HLRZ	T3,(T2)			;Get the length of the block
	CAIGE	T3,(T1)			;Check big enough..
	 JRST	ALLPA9			;No. Don't look any futher
	MOVEM	T2,@-1(P)		;Return address of allocated page(s)
	HRRZ	T4,(T2)			;Get forward pointer
	SUBI	T3,(T1)			;Reduce length by amount we want
	JUMPN	T3,ALLPA2		;Any left?
	HRRM	T4,FFREE		;No. Next block is now first free
	MOVEI	T1,1			;Success.
	RET

ALLPA2:	ADDI	T2,(T1)			;Point to new first free
	HRLM	T3,(T2)			;Store updated length
	HRRM	T4,(T2)			;Store forward pointer
	HRRM	T2,FFREE		;Update first free pointer
	MOVEI 1,1			;Success.
	RET

ALLPA9:	SETZ	T1,			;Return failure
	RET

	PAGE
	SUBTTL	DEAPAG - Deallocate a page

; DEALLOCATE PAGES OF HEAP STORAGE
;
; ARGUMENTS ON STACK:-
;	# PAGES BEING RELEASED
;	ADDRESS OF FIRST WORD TO BE RELEASED
;

DEAPAG::
	MOVE	T2,@-2(P)		;Get size
	IMULI	T2,^D512		;Convert to words
	JRST	DEAHE0			;Use common code

	PAGE
	SUBTTL	DEAMEM - Deallocate all memory

;DEALLOCATE ALL ALLOCATED MEMEORY
;
;NO ARGUMENTS ARE REQUIRED AND NO VALUE IS RETURNED

DEAMEM:
	MOVN	T4,FREPGS		;Make an AOBJN pointer to first page
	MOVSS	T4
	HRRI	T4,^D256		;Last+1 = page 400
	SUB	T4,FREPGS		;-count,,first
DEMEM1:
	MOVSI	T1,.FHSLF
	HRRI	T1,(T4)			;Get a page to test
	RPACS				;See what access we have
	 ERJMP	.+1
	TXNN	T2,PA%PEX		;Does it exist?
	 JRST	DEMEM2			;No - ignore it
	MOVE	T2,T1			;Copy page number
	SETO	T1,
	SETZ	T3,			;Just one page
	PMAP				;Lose it
	 ERJMP	.+1
DEMEM2:
	AOBJN	T4,DEMEM1		;Loop over all pages
	SETZM	INIT
	SETZM	FREPGS			;Clean up
	RET				;Done
	
	PAGE
	SUBTTL	INIMEM - Initialise memory

INIMEM:
	HRRZI	T3,^D256		;Setup a count
INIM01:	MOVSI	T1,.FHSLF		;Get page access bits
	HRRI	T1,-1(T3)		;...
	RPACS				;...
	 ERJMP	.+1			;...
	JUMPN	T2,INIM02		;Jump if existing page
	SOJGE	T3,INIM01		;Loop for loseg addresses

INIM02:	MOVEI	T1,^D256		;Compute no. of free pages
	SUBI	T1,(T3)			;...
	MOVEM	T1,FREPGS		;Save number of pages "allocated"
	IMULI	T1,^D512		;Convert to words.
	IMULI	T3,^D512		;Get address of first free page
	HRLZM	T1,(T3)			;Store length of free block
	MOVEM	T3,FFREE		;Point to first free block
	MOVEM	T3,FFLOW		;Save absolute low limit
	SETOM	INIT			;Flag memory initialised
	RET

	END