.TITLE AALLOCX .ident /X01.03/ .enabl lc, gbl .nlist bex ; .list meb ; ; Utility Routines ; Dynamic Space Management ; ; Version x01 ; ; David G. Conroy 12-Dec-77 ; ; ; Edit history ; 01 01-Aug-79 MM Added RT11 support ; 02 16-Feb-81 MM Removed EIS ; 03 27-Feb-82 RBD Use unsigned compare for addresses. Bit me on TSX+ ; Globalize HILOCN for AS ; ; Note: ; This routine is used only in the compiler/assembler library. ; Work areas are forced into the root segment by allocating the ; aldata .psect in CC0RT. ; .globl $alloc .globl $free .globl hilocn ;03 .mcall call .mcall callr .mcall return .MCALL GTSK$S .mcall extk$s ; ; Equivalences ; LINK must be 0. ; LINK = 0 ;Link to next block in free list SIZE = 2 ;Size of the block SLOP = 8. ;Fuzz factor for space allocation ; ; Local Data (The RT11 linker requires this to be in the root). ; limits: .limit ;Load sizes (set by TKB) GTSBUF: .BLKW 16. ;WORK BUFFER FOR GTSK$S avail: .word 0 .word 0 hilocn:: ;03 .word 0 ;Highest loc+1 in partition (zero if not set) .even ;+ ; ** $alloc -- allocate space ; ; This routine allocates a block of memory from the global free ; list. This list is automatically set up by '$alloc' on the ; first call. ; ; If there is insufficient space to allocate the block and task ; extension has failed, $alloc calls the routine $deny and then ; returns whatever $deny leaves in r0. ; ; Inputs: ; r0=size of block desired (bytes) ; ; Outputs: ; r0=pointer to block ;- $alloc: mov r3,-(sp) ;Save registers mov r2,-(sp) mov r1,-(sp) tst hilocn ;Is this the first call bne 20$ ;Br if not mov r0,-(sp) ;Save size requested mov limits+2,r0 ;Get top address of task add #3,r0 ;Round up mod 4 bic #3,r0 GTSK$S #GTSBUF ;GET TASK PARAMETERS bcs 110$ ;Something is nasty in the nursery MOV GTSBUF+G.TSTS,R1 ;R1=HIGHEST ADDR+1 mov r1,hilocn ;save new top of core sub r0,r1 ;Get size of core hole cmp r1,#4 ;If very small core hole blo 10$ ;It cannot be freed ;01/03 mov r1,(r0)+ ;Otherwise free it call $free 10$: mov (sp)+,r0 ;Get requested size back 20$: add #2+1,r0 ;1 control word + rounding bic #1,r0 cmp r0,#4 ;Check for bad call blo 110$ ;Abort if allocating zero words mov r0,r1 ;Save rounded size 30$: mov #avail,r3 ;Points to free list header 40$: mov (r3),r2 ;mov LINK(r3),r2 beq 80$ ;No space on the free list cmp SIZE(r2),r0 ;Is it usable bhis 50$ mov r2,r3 ;No, continue the search br 40$ 50$: neg r0 ;Compute what is left over add SIZE(r2),r0 cmp r0,#SLOP ;Do we want to leave what is left over bhis 60$ ;Yes mov (r2),(r3) ;No, unlink the block mov r2,r0 ;Setup for return mov SIZE(r2),(r0)+ br 100$ 60$: mov r0,SIZE(r2) ;Adjust size in the block add r2,r0 ;Get pointer to the space to return mov r1,(r0)+ ;Put size in it br 100$ ;Return ; ; Out of space ; Try to extend the task. ; 80$: add #77,r0 ;Get grow increment bic #77,r0 mov r0,r2 ;Save it, then ; ash #-6,r0 ;Convert to 32 word blocks asr r0 ;02+ asr r0 asr r0 asr r0 asr r0 asr r0 ;02- extk$s r0 ;Try to grow bcs 90$ ;No mov hilocn,r0 ;Return new block to free list add r2,hilocn mov r2,(r0)+ call $free mov r1,r0 ;Setup size again, and br 30$ ;Try again (must work) 90$: call $deny ;No space 100$: mov (sp)+,r1 ;Return mov (sp)+,r2 mov (sp)+,r3 return 110$: CRASH ;Nasty ;+ ; ** $free -- free space (obtained from '$alloc') ; ; This routine returns a block of memory, previously obtained ; from '$alloc', to the free pool. ; Needless to say, grave disorder will result if some random ; integer is passed to '$free', or you try to '$free' some ; space twice. ; ; Inputs: ; r0=pointer to the space ;- $free: mov r4,-(sp) ;Save some registers mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov r0,-(sp) mov -(r0),r1 ;Fix pointer, get size mov #avail,r3 ;Free list pointer 10$: mov (r3),r2 ;Walk down the list until beq 30$ ;The end cmp r2,r0 ;Or the correct place is found bhi 20$ mov r2,r3 br 10$ 20$: mov r0,r4 ;Test for collapse top end add r1,r4 cmp r4,r2 ;If they hit bne 30$ add SIZE(r2),r1 ;Join them together mov (r2),(r0) br 40$ 30$: mov r2,(r0) ;Otherwise just link it in 40$: mov r3,r4 ;Test for collapse bottom end add SIZE(r3),r4 cmp r4,r0 bne 50$ add r1,SIZE(r3) ;Merge them mov (r0),(r3) br 60$ 50$: mov r0,(r3) ;Otherwise finish linking it in mov r1,SIZE(r0) 60$: mov (sp)+,r0 ;Return mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 return .END