make mem.free O(1) with some linked list voodoo thank you bill gates
This commit is contained in:
100
src/std/std.zr
100
src/std/std.zr
@@ -4,12 +4,13 @@ func panic[msg: str] : void
|
|||||||
(0 / 0) // crashes program which is kinda better since you get a gdb backtrace
|
(0 / 0) // crashes program which is kinda better since you get a gdb backtrace
|
||||||
os.exit(1)
|
os.exit(1)
|
||||||
|
|
||||||
const MEM_BLOCK_SIZE = 24
|
const MEM_BLOCK_SIZE = 32
|
||||||
|
|
||||||
struct mem.Block
|
struct mem.Block
|
||||||
size: i64
|
size: i64
|
||||||
free: bool
|
free: bool
|
||||||
next: mem.Block
|
next: mem.Block
|
||||||
|
prev: mem.Block
|
||||||
|
|
||||||
func mem._align[x: i64] : i64
|
func mem._align[x: i64] : i64
|
||||||
return (x + 7) & -8
|
return (x + 7) & -8
|
||||||
@@ -20,13 +21,17 @@ func mem._split_block[blk: mem.Block, needed: i64] : void
|
|||||||
new_blk->size = blk->size - needed - MEM_BLOCK_SIZE
|
new_blk->size = blk->size - needed - MEM_BLOCK_SIZE
|
||||||
new_blk->free = true
|
new_blk->free = true
|
||||||
new_blk->next = blk->next
|
new_blk->next = blk->next
|
||||||
|
new_blk->prev = blk
|
||||||
|
|
||||||
|
if blk->next
|
||||||
|
let next: mem.Block = blk->next
|
||||||
|
next->prev = new_blk
|
||||||
|
else
|
||||||
|
mem.write64(_builtin_heap_tail(), new_blk)
|
||||||
|
|
||||||
blk->size = needed
|
blk->size = needed
|
||||||
blk->next = new_blk
|
blk->next = new_blk
|
||||||
|
|
||||||
if mem.read64(_builtin_heap_tail()) == blk
|
|
||||||
mem.write64(_builtin_heap_tail(), new_blk)
|
|
||||||
|
|
||||||
func mem._request_space[size: i64] : mem.Block
|
func mem._request_space[size: i64] : mem.Block
|
||||||
let needed: i64 = size + MEM_BLOCK_SIZE
|
let needed: i64 = size + MEM_BLOCK_SIZE
|
||||||
let alloc_size: i64 = (needed + 4095) & -4096
|
let alloc_size: i64 = (needed + 4095) & -4096
|
||||||
@@ -41,48 +46,16 @@ func mem._request_space[size: i64] : mem.Block
|
|||||||
blk->size = alloc_size - MEM_BLOCK_SIZE
|
blk->size = alloc_size - MEM_BLOCK_SIZE
|
||||||
blk->free = false
|
blk->free = false
|
||||||
blk->next = 0
|
blk->next = 0
|
||||||
|
blk->prev = 0
|
||||||
|
|
||||||
let tail: mem.Block = mem.read64(_builtin_heap_tail())
|
let tail: mem.Block = mem.read64(_builtin_heap_tail())
|
||||||
if tail
|
if tail
|
||||||
tail->next = blk
|
tail->next = blk
|
||||||
|
blk->prev = tail
|
||||||
|
|
||||||
mem.write64(_builtin_heap_tail(), blk)
|
mem.write64(_builtin_heap_tail(), blk)
|
||||||
return blk
|
return blk
|
||||||
|
|
||||||
func mem._coalesce[] : void
|
|
||||||
let cur: mem.Block = mem.read64(_builtin_heap_head())
|
|
||||||
let prev: mem.Block = 0
|
|
||||||
|
|
||||||
while cur
|
|
||||||
let next: mem.Block = cur->next
|
|
||||||
let expected_next: mem.Block = cur + MEM_BLOCK_SIZE + cur->size
|
|
||||||
|
|
||||||
if cur->free && next && next->free && expected_next == next
|
|
||||||
cur->size = cur->size + MEM_BLOCK_SIZE + next->size
|
|
||||||
cur->next = next->next
|
|
||||||
if !cur->next
|
|
||||||
mem.write64(_builtin_heap_tail(), cur)
|
|
||||||
continue
|
|
||||||
|
|
||||||
let block_total: i64 = cur->size + MEM_BLOCK_SIZE
|
|
||||||
if cur->free && (cur & 4095) == 0 && (block_total & 4095) == 0
|
|
||||||
if prev
|
|
||||||
prev->next = cur->next
|
|
||||||
if !cur->next
|
|
||||||
mem.write64(_builtin_heap_tail(), prev)
|
|
||||||
else
|
|
||||||
mem.write64(_builtin_heap_head(), cur->next)
|
|
||||||
if !cur->next
|
|
||||||
mem.write64(_builtin_heap_tail(), 0)
|
|
||||||
|
|
||||||
let saved_next: mem.Block = cur->next
|
|
||||||
_builtin_syscall(SYS_munmap, cur, block_total)
|
|
||||||
cur = saved_next
|
|
||||||
continue
|
|
||||||
|
|
||||||
prev = cur
|
|
||||||
cur = cur->next
|
|
||||||
|
|
||||||
func mem.alloc[size: i64] : ptr
|
func mem.alloc[size: i64] : ptr
|
||||||
if size == 0
|
if size == 0
|
||||||
return 0
|
return 0
|
||||||
@@ -109,10 +82,50 @@ func mem.alloc[size: i64] : ptr
|
|||||||
return blk + MEM_BLOCK_SIZE
|
return blk + MEM_BLOCK_SIZE
|
||||||
|
|
||||||
func mem.free[x: ptr] : void
|
func mem.free[x: ptr] : void
|
||||||
if x
|
if !x
|
||||||
|
return 0
|
||||||
|
|
||||||
let blk: mem.Block = x - MEM_BLOCK_SIZE
|
let blk: mem.Block = x - MEM_BLOCK_SIZE
|
||||||
blk->free = true
|
blk->free = true
|
||||||
mem._coalesce()
|
|
||||||
|
let next: mem.Block = blk->next
|
||||||
|
if next && next->free
|
||||||
|
let expected_next: mem.Block = blk + MEM_BLOCK_SIZE + blk->size
|
||||||
|
if expected_next == next
|
||||||
|
blk->size = blk->size + MEM_BLOCK_SIZE + next->size
|
||||||
|
blk->next = next->next
|
||||||
|
if next->next
|
||||||
|
let b: mem.Block = next->next
|
||||||
|
b->prev = blk
|
||||||
|
if mem.read64(_builtin_heap_tail()) == next
|
||||||
|
mem.write64(_builtin_heap_tail(), blk)
|
||||||
|
|
||||||
|
let prev: mem.Block = blk->prev
|
||||||
|
if prev && prev->free
|
||||||
|
let expected_blk: mem.Block = prev + MEM_BLOCK_SIZE + prev->size
|
||||||
|
if expected_blk == blk
|
||||||
|
prev->size = prev->size + MEM_BLOCK_SIZE + blk->size
|
||||||
|
prev->next = blk->next
|
||||||
|
if blk->next
|
||||||
|
let b: mem.Block = blk->next
|
||||||
|
b->prev = prev
|
||||||
|
if mem.read64(_builtin_heap_tail()) == blk
|
||||||
|
mem.write64(_builtin_heap_tail(), prev)
|
||||||
|
blk = prev
|
||||||
|
|
||||||
|
let block_total: i64 = blk->size + MEM_BLOCK_SIZE
|
||||||
|
if (blk & 4095) == 0 && (block_total & 4095) == 0
|
||||||
|
if blk->prev
|
||||||
|
let b: mem.Block = blk->prev
|
||||||
|
b->next = blk->next
|
||||||
|
else
|
||||||
|
mem.write64(_builtin_heap_head(), blk->next)
|
||||||
|
if blk->next
|
||||||
|
let b: mem.Block = blk->next
|
||||||
|
b->prev = blk->prev
|
||||||
|
else
|
||||||
|
mem.write64(_builtin_heap_tail(), blk->prev)
|
||||||
|
_builtin_syscall(SYS_munmap, blk, block_total)
|
||||||
|
|
||||||
func mem.realloc[x: ptr, new_size: i64] : ptr
|
func mem.realloc[x: ptr, new_size: i64] : ptr
|
||||||
if !x
|
if !x
|
||||||
@@ -137,7 +150,10 @@ func mem.realloc[x: ptr, new_size: i64] : ptr
|
|||||||
if combined >= new_size
|
if combined >= new_size
|
||||||
blk->size = combined
|
blk->size = combined
|
||||||
blk->next = next->next
|
blk->next = next->next
|
||||||
if !blk->next
|
if next->next
|
||||||
|
let b: mem.Block = next->next
|
||||||
|
b->prev = blk
|
||||||
|
if mem.read64(_builtin_heap_tail()) == next
|
||||||
mem.write64(_builtin_heap_tail(), blk)
|
mem.write64(_builtin_heap_tail(), blk)
|
||||||
mem._split_block(blk, new_size)
|
mem._split_block(blk, new_size)
|
||||||
return x
|
return x
|
||||||
@@ -319,7 +335,7 @@ func io.read_binary_file[path: str] : io.Buffer
|
|||||||
_builtin_syscall(SYS_lseek, fd, 0, 0)
|
_builtin_syscall(SYS_lseek, fd, 0, 0)
|
||||||
|
|
||||||
buffer->data = mem.alloc(buffer->size)
|
buffer->data = mem.alloc(buffer->size)
|
||||||
_builtin_syscall(SYS_read, fd, buffer->data, buffer->size)
|
let n: i64 = _builtin_syscall(SYS_read, fd, buffer->data, buffer->size)
|
||||||
_builtin_syscall(SYS_close, fd)
|
_builtin_syscall(SYS_close, fd)
|
||||||
|
|
||||||
if n < 0
|
if n < 0
|
||||||
|
|||||||
Reference in New Issue
Block a user