/ /lws001 2-jan-80 Correct allocation in case task is pr:4 or 5 / / / Dynamic space manager. / .globl alloc .globl free .globl calloc .globl cfree .globl malloc .globl mfree .globl freesp .globl __aloc .globl __free .globl __mavl .globl __mtop .globl __mlim SLOP = 8. /Fuzz EXTK = 89.+[3.<<8.] /EXTK dic GPRT = 65.+[4.<<8.] /GPRT dic __mavl: 0 /Free list head 0 __mtop: 0 /Top of mem+1 (0 if not set) __mlim: .limit /Limits bcm: .asciz "Bad call to `__free' (%06o)\n" .even / / User interface. / char *malloc(n); /* If no space, NULL */ / char *alloc(n); /* If no space, -1 */ / char *calloc(n, m); /* If no space, NULL; zeroed */ / / mfree(p); / free(p); / cfree(p); / / int freespace(); / alloc: mov 2(sp),r0 / Grab size. call __aloc / Try to allocate the space. tst r0 / Well ? bne 0f / Br if all ok. mov $-1,r0 / Convert NULL to -1 0: return / Done. calloc: jsr r0,__csav / Get some registers ! mov 12(r5),-(sp) / Get size in bytes. mov 14(r5),-(sp) / call mul_i / mov r0,r4 / Save size. call __aloc / Try to allocate the space. tst r0 / Ok ? beq 1f / No, just duck. mov r0,r3 / Copy pointer to space. 0: dec r4 / Clear bmi 1f / Out. clrb (r3)+ / the br 0b / storage. 1: jmp __cret / Done. malloc: mov 2(sp),r0 / Grab size. callr __aloc / Try to allrocate the space. free: cfree: mfree: mov 2(sp),r0 callr __free freesp: clr r0 mov __mavl,r1 beq 1f 0: add 2(r1),r0 mov (r1),r1 bne 0b 1: return / / __aloc. / Internal allocate routine. / Input: r0=size (bytes). / Output: r0=ptr to space or NULL. / __aloc: mov r3,-(sp) /Save registers mov r2,-(sp) tst __mtop /First call ? bne 1f /Br if not mov r0,r3 /Save size sub $6,sp /Get a GPRT buffer mov sp,r1 /Do it mov r1,-(sp) /Big cheer for the PDP-11 !! clr -(sp) clr -(sp) mov $GPRT,-(sp) emt 377 bcc 0f /Ok add $6,sp /Say no space br 2f 0: mov 2(sp),r1 /Size (clicks) asl r1 /Convert to bytes asl r1 asl r1 asl r1 asl r1 asl r1 add _dsw,r1 /Top of memory (Correctly!) /+ lws001 / /Check stack size to determine if task is pr:4 or 5 / mov __mlim, r0 /Lowest possible value for stack bic $17777,r0 /Get rid of values <16k wds add r0,r1 /If r0 not 0, task is probably priv. /- lws001 mov r1,__mtop add $6,sp /Discard buffer mov __mlim+2,r0 /Base of core hole sub r0,r1 /Get its size cmp r1,$4 /Big enough to save ? blo 0f /No mov r0,(r0) /mov r0,(r0)+ screws up tst (r0)+ /on some cpu's. mov r1,(r0)+ call __free 0: mov r3,r0 /Get size back 1: add $4+1,r0 /2 words + round bic $1,r0 cmp r0,$6 /Check for bad call blo 2f /Abort if allocating zero words 1: mov r0,r1 /Save rounded size mov $__mavl,r3 /Point at free list 0: mov (r3),r2 /mov LINK(r3),r2 beq 4f /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 r0,(r0) /Check word tst (r0)+ / 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 r0,(r0) /Check word tst (r0)+ / mov r1,(r0)+ /Put size in it br 3f /Return / / Out of space. / Try to grow. / 4: mov r0,r3 /Save size add $377,r0 /Get grow increment clrb r0 mov r0,r2 /Save it, then ror r0 /Convert to clicks (c clear!) ror r0 ror r0 ror r0 ror r0 ror r0 clr -(sp) /EXTK$S r0 mov r0,-(sp) mov $EXTK,-(sp) emt 377 bcs 2f /No core ! mov __mtop,r0 /Get base of new mem. add r2,__mtop /Adjust top. mov r0,(r0) /Free new core. tst (r0)+ / mov r2,(r0)+ call __free mov r3,r0 /Get size back and br 1b /Try again 2: clr r0 /Return NULL 3: mov (sp)+,r2 /Return mov (sp)+,r3 return / / __free. / Internal free routine. / Input: r0=ptr to block. / If the block is not a valid alloc / block it exits with the message / "Bad call to `__free' (nnnnnn). / __free: mov r4,-(sp) /Save some registers mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov -(r0),r1 /Get size cmp -(r0),r0 /Valid ? beq 0f /Probably cmp (r0)+,(r0)+ /Put caller's arg. back mov r0,-(sp) /Print message mov $bcm,-(sp) call error iot /Hmmmmm ... 0: mov $__mavl,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