/ / PDP-11 C. / Standard Library. / / Dynamic space management. / .globl alloc .globl free .globl calloc .globl cfree .globl _alloc .globl _free .globl _avail .globl exttsk .globl deny .globl getpar .globl _mul .globl _asr SLOP = 8. /Fuzz factor for space allocation _avail: .word 0,0 /Free list hi: .word 0 /Top of partition (0 if not set) pb: .blkw 4 /For getpar() lim: .limit /Load limits / / These routines provide the user's interface / to the allocator. / Note that `free' and `cfree' are the same routine. / / alloc(nbytes) / calloc(n, nbytes) / free(p) / cfree(p) / alloc: mov 2(sp),r0 br 0f calloc: call _mul /multiply the two arguments 0: callr _alloc free: cfree: mov 2(sp),r0 callr _free / / _alloc / Allocate space (internal interface). / / 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' returns whatever the function / `deny' (of 0 arguments) returns. The default `deny' returns / -1. / / r0=size of the desired block. / r0=return pointer. / _alloc: mov r3,-(sp) /Save registers mov r2,-(sp) tst hi /Is this the first call bne 1f /Br if not mov r0,-(sp) /Save size requested mov $pb,-(sp) /Get partition parameters call getpar tst (sp)+ mov pb+4,r1 /Compute size asl r1 asl r1 asl r1 asl r1 asl r1 asl r1 add pb+2,r1 mov r1,hi mov lim+2,r0 /Compute size of core hole add $3,r0 bic $3,r0 sub r0,r1 cmp r1,$4 /If very small core hole blo 0f /It cannot be freed mov r1,(r0)+ /Otherwise free it call _free 0: mov (sp)+,r0 /Get request size back 1: add $2+1,r0 /1 control word + rounding bic $1,r0 cmp r0,$4 /Check for bad call blo 4f /Abort if allocating zero words mov r0,r1 /Save rounded size 1: mov $_avail,r3 /Point at free list 0: mov (r3),r2 /mov LINK(r3),r2 beq 2f /No space on the free list cmp 2(r2),r0 /Is it usable bhis 0f mov r2,r3 /No, continue the search br 0b 0: neg r0 /Compute leftover add 2(r2),r0 cmp r0,$SLOP /Use it all bhis 0f /No mov (r2),(r3) /Yes, unlink the block mov r2,r0 /Setup for return mov 2(r2),(r0)+ br 3f 0: mov r0,2(r2) /Adjust size in the block add r2,r0 /Get pointer to the space to return mov r1,(r0)+ /Put size in it br 3f /Return / / Out of space. / Try to extend the task. / In RSX-11M V02, just die. / 2: add $77,r0 /Get grow increment bic $77,r0 mov r0,r2 /Save it, then mov r1,-(sp) /save r1 mov $6,-(sp) /shift count mov r0,-(sp) /stuff to be shifted call _asr /convert to 32 word blocks tst (sp)+ /clean stack tst (sp)+ /clean stack mov (sp)+,r1 /restore r1 mov r0,-(sp) /Try to grow call exttsk tst (sp)+ cmp r0,$-1 beq 0f /Failed mov hi,r0 /Return new block to free list add r2,hi mov r2,(r0)+ call _free mov r1,r0 /Setup size again, and br 1b /Try again (must work) 0: call deny /No space 3: mov (sp)+,r2 /Return mov (sp)+,r3 return 4: iot /Allocating zero words / / _free / Free space (internal interface). / / 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. / / r0=pointer to the block to free. / / Uses: r0 / _free: mov r4,-(sp) /Save some registers mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov -(r0),r1 /Fix pointer, get size mov $_avail,r3 /Free list pointer 0: mov (r3),r2 /Walk down the list until beq 1f /The end cmp r2,r0 /Or the correct place is found bhi 0f mov r2,r3 br 0b 0: mov r0,r4 /Test for collapse top end add r1,r4 cmp r4,r2 /If they hit bne 1f add 2(r2),r1 /Join them together mov (r2),(r0) br 0f 1: mov r2,(r0) /Otherwise just link it in 0: mov r3,r4 /Test for collapse bottom end add 2(r3),r4 cmp r4,r0 bne 1f add r1,2(r3) /Merge them mov (r0),(r3) br 0f 1: mov r0,(r3) /Otherwise finish linking it in mov r1,2(r0) 0: mov (sp)+,r1 /Return mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 return