nxu/mem-arena.tal

79 lines
2.2 KiB
Tal

( alloc.tal )
( )
( simple arena allocator )
( )
( the idea here is to pre-allocate a large arena of memory )
( and then keep a pointer to the first unallocated byte. )
( memory is released in reverse order of when it was allocated. )
( )
( in this example we're preallocating 16,384 bytes (#4000) )
( located at mem-arena. we're using mem-cursor to point to )
( the next unallocated byte. )
( )
( if mem-cursor ever contains the address of mem-cursor it )
( means we've reached the limit of what we can allocate. )
( we raise divide-by-zero errors if we cannot allocate )
( or release memory as requested. )
( )
( memory can be freed by size (number of bytes) or cleared )
( all at once. )
( macro to allocate one byte of memory )
%mem-alloc-byte { #0001 ;mem-alloc JMP2r } ( -> addr* )
( macro to allocate two bytes of memory )
%mem-alloc-short { #0002 ;mem-alloc JMP2r } ( -> addr* )
( macro to allocate an 8-bit count of memory (n) )
%mem-alloc8 { #00 SWP ;mem-alloc JMP2r } ( n^ -> addr* )
( macro to allocate a 16-bit count of memory (n) )
%mem-alloc16 { ;mem-alloc JMP2r } ( n* -> addr* )
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 ]
|0100
;mem-init JSR2
;on-input .Console/vector DEO2
;mem-cursor LDA2 ;start STA2
BRK
@start $2
@on-input
.Console/read DEI DUP ,&continue JCN
( ;on-complete JSR2 ) POP BRK
&continue ( mem-alloc-byte STA ) BRK
@on-complete
;mem-cursor LDA2 STH2
;start LDA2
&loop
DUP2 STH2kr LTH2 ,&continue JCN
;mem-init JSR2 POP2 POP2r JMP2r
&continue
LDA2k .Console/write DEO
INC2 ,&loop JMP
( allocate n bytes of memory )
@mem-alloc ( n* -> addr* )
;mem-cursor LDA2 ADD2 DUP2 ( new-addr new-addr )
;mem-cursor LTH2 ,&ok JCN DIV2 #0000 ( fail if we reach mem-cursor's own address )
&ok DUP2 ;mem-cursor STA2 JMP2r
( initialize memory, release all allocated memory )
@mem-init ( -> )
;mem-arena ;mem-cursor STA2 JMP2r
( release n bytes of allocated memory )
@mem-release ( n* -> )
;mem-cursor LDA2 SUB2 DUP2 ( new-addr new-addr )
;mem-arena LTH2 ,&fail JCN ;mem-cursor STA2 JMP2r
&fail DIV2 #0000 ( fail if we reach beyond mem-arena's own address )
( location of the memory to be allocated )
@mem-arena $4000
( pointer to the next free byte, if any )
@mem-cursor $2