commit 12eb9c4837b9395ae89a93625775574e9e77dabe
parent 217157c2e5611b9da96bb6fa336a33f706aab777
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sat, 14 Jan 2023 21:58:45 -0500
lib/alloc: add :ensure
Diffstat:
2 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/fs/doc/lib/alloc.txt b/fs/doc/lib/alloc.txt
@@ -54,37 +54,50 @@ Example usage:
### Scratchpad's API
-:new ( sz -- pad ) create a new scratchpad of sz bytes in length
-
-:allot ( n pad -- a ) allocate n bytes in the pad and return the address of the
-allocated memory space.
-
-:move ( src u pad -- a ) allocate u bytes on the pad and copy the range "src u"
-into it. Then, return the allocated memory space.
-
-:[]>str ( a u pad -- str ) allocate u bytes on the pad and copy that range to it
-as an encoded string, then return that string.
-
-:[ ( sz pad -- ) reserve sz bytes on the pad (we don't allocate it yet, but we
-ensure that there's at least that many bytes left in the buffer) and make "here"
-point to that reserved buffer. From that point on, all "write" words will write
-to that buffer. When you're finished, call :]
-
-:] ( pad -- a ) finalize a :[ operation by allocating the actual number of bytes
-that were written to "here". If that number was less than reserved, we only
-allocate that lesser size. If it was higher, we error out (you never want to go
-over that limit because that means corrupting your system memory). Restore
-"here" to the value it had before the :[ call. Then, return the memory address
-if the allocated memory.
-
-:, ( n pad ) shortcut for "4 :[ , :] drop"
-
-:s, ( str pad -- ) write string str to the pad.
-
-:freesz ( pad -- sz ) number of bytes left in the buffer before it rolls over.
-
-:usedsz ( pad -- sz ) number of bytes used in the buffer so far. Goes back to 0
-after a rollover.
+:new ( sz -- pad )
+ create a new scratchpad of sz bytes in length
+
+:ensure ( n pad -- )
+ Ensure that the pad has at least "n" bytes of contiguous memory available. If
+ not, rollover.
+
+:allot ( n pad -- a )
+ allocate n bytes in the pad and return the address of the allocated memory
+ space.
+
+:move ( src u pad -- a )
+ allocate u bytes on the pad and copy the range "src u" into it. Then, return
+ the allocated memory space.
+
+:[]>str ( a u pad -- str )
+ allocate u bytes on the pad and copy that range to it as an encoded string,
+ then return that string.
+
+:[ ( sz pad -- )
+ reserve sz bytes on the pad (we don't allocate it yet, but we ensure that
+ there's at least that many bytes left in the buffer) and make "here" point to
+ that reserved buffer. From that point on, all "write" words will write to that
+ buffer. When you're finished, call :]
+
+:] ( pad -- a )
+ finalize a :[ operation by allocating the actual number of bytes that were
+ written to "here". If that number was less than reserved, we only allocate
+ that lesser size. If it was higher, we error out (you never want to go over
+ that limit because that means corrupting your system memory). Restore "here"
+ to the value it had before the :[ call. Then, return the memory address of the
+ allocated memory.
+
+:, ( n pad )
+ shortcut for "4 :[ , :] drop"
+
+:s, ( str pad -- )
+ write string str to the pad.
+
+:freesz ( pad -- sz )
+ number of bytes left in the buffer before it rolls over.
+
+:usedsz ( pad -- sz )
+ number of bytes used in the buffer so far. Goes back to 0 after a rollover.
:reset ( pad -- ) empty the buffer and resets its pointers.
diff --git a/fs/lib/alloc.fs b/fs/lib/alloc.fs
@@ -15,9 +15,11 @@ struct[ Allocator
: :freesz dup :)buf swap ptr - ;
+ : :ensure ( n self -- )
+ dup :freesz rot < if dup :findspace swap to ptr else drop then ;
+
: :allot ( n self -- a )
- dup >r :freesz over < if r@ :findspace else r@ ptr then ( n a )
- tuck + to r> ptr ( a ) ;
+ 2dup :ensure dup ptr rot> to+ ptr ;
: :move ( src u self -- a )
over swap :allot ( src u dst ) tuck >r move r> ;