Skip to content
This repository was archived by the owner on Nov 11, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions examples/dynamic-memory.porth
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
include "std.porth"
include "dynamic-memory.porth"

// Test raw memory allocation
"Allocating memory without housekeeping\n" puts

4096 palloc_raw
"Pointer: " puts
dup print

4096 palloc_raw
"Pointer: " puts
dup print

// is the difference equal to page size?
"Difference: " puts
over over - abs
print
"(should be =4096 if addresses aren't randomized)\n" puts
// CLEAN UP!
4096 pfree_raw
4096 pfree_raw // needs to take the size

"\n" puts

// Test housekeeping
"Allocating memory with housekeeping\n" puts

4096 palloc
"Pointer: " puts
dup print

4096 palloc
"Pointer: " puts
dup print

// is the difference the page size?
"Difference: " puts
over over - abs
print
"(should be >4096 due to housekeeping)\n" puts
// clean up - no need to worry about size
pfree
pfree
70 changes: 70 additions & 0 deletions std/dynamic-memory.porth
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// requires std.porth - currently there's no include guards so do this yourself!

// TODO: Get from include files, or run C preprocessor?
macro PROT_READ 1 end
macro PROT_WRITE 2 end
macro MAP_PRIVATE 2 end
macro MAP_ANONYMOUS 32 end

macro exit_if_failed
// stack: ptr
// if failed: exit(1)
// if succeeded: leave ptr on stack
if dup 0 < do
"Failed to allocate memory!\n" puts
1 exit
end
end

macro palloc_raw
// takes length of memory to be allocated in bytes
// returns pointer to the start
// void *addr, size_t length, int prot, int flags, int fd, off_t offset SYSCALL_NUMBER
0 swap
-1 swap
MAP_PRIVATE MAP_ANONYMOUS or swap
PROT_READ PROT_WRITE or swap
NULL
SYS_mmap
syscall6
// stack is now: size, returncode/ptr

exit_if_failed
cast(ptr)
end
macro palloc
// allocates a page, but no need to keep track of the size
// may allocate more in order to store the length
// pointer returned is still start of useable space (so can write to *ptr but shouldn't write to *(ptr-8))
8 + // need 8 bytes extra allocated for housekeeping
dup // keep size for later

palloc_raw

// stick size on the front, for housekeeping
swap over !64
// left with just the pointer
8 +
end

macro pfree_raw
// Takes pointer, size on stack
swap
SYS_munmap
syscall2
if dup 0 != do
"Error freeing: " puts print " not equal to 0\n" puts
else
drop
"Freed successfully\n" puts
end
end

macro pfree
// takes pointer of allocated memory
// size stored at ptr - 8
8 -
dup
@64
pfree_raw
end
6 changes: 6 additions & 0 deletions std/std.porth
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,12 @@ macro dec64
dup ,64 1 - .64
end

macro abs
if dup 0 < do
0 over - swap drop
end
end

macro cstrlen
dup
while dup , 0 != do 1 + end
Expand Down