FREE SEEMS TO WORK POG

This commit is contained in:
Bryan McShea
2022-10-20 22:57:47 -04:00
parent 4590c5ea62
commit de5c57ef9e
2 changed files with 152 additions and 59 deletions

View File

@@ -13,12 +13,13 @@
# block node # block node
.equ binfo, 0 .equ binfo, 0
.equ fb_next, 8 # free only .equ fb_prev, 8 # free only
.equ fb_next, 16 # free only
# free also contains its address at the end # free also contains its address at the end
# sizes of metadata # sizes of metadata
.equ sizeof_fb, (8*3 + align_imask) & align_mask .equ sizeof_fb, (8*4 + align_imask) & align_mask
.equ sizeof_ub, (8*1 + align_imask) & align_mask .equ sizeof_ub, (8*1 + align_imask) & align_mask
.equ PAGE_SIZE, 4096 .equ PAGE_SIZE, 4096
@@ -39,10 +40,12 @@ heap_oom:
.global heap_info # global for testing only .global heap_info # global for testing only
.equ heap_last_used, 0 # is the last block used; .equ heap_last_used, 0 # is the last block used;
# matches binfo # matches binfo
.equ heap_first_free, 8 # matches fb_next .equ heap_last_free, 8 # matches fb_prev
.equ heap_start, 16 .equ heap_first_free, 16 # matches fb_next
.equ heap_end, 24 .equ heap_start, 24
.equ heap_end, 32
heap_info: heap_info:
.dword 0
.dword 0 .dword 0
.dword 0 .dword 0
.dword __global_pointer$ .dword __global_pointer$
@@ -91,9 +94,11 @@ heap_init:
ori t2, t2, prev_used # add prev used ori t2, t2, prev_used # add prev used
sd t2, binfo(t1) # store size sd t2, binfo(t1) # store size
sd t0, fb_next(t1) # store next sd t0, fb_next(t1) # store next
sd t0, fb_prev(t1) # store prev
sd t1, -8(a0) # store addr at end sd t1, -8(a0) # store addr at end
sd t1, heap_first_free(t0) sd t1, heap_first_free(t0)
sd t1, heap_last_free(t0)
ld ra, 0(sp) ld ra, 0(sp)
addi sp, sp, +8 addi sp, sp, +8
@@ -159,7 +164,7 @@ heap_alloc:
sub t2, a0, t1 # new free space (t2) sub t2, a0, t1 # new free space (t2)
andi t5, t2, prev_used # prev used bit andi t5, t2, prev_used # prev used bit
sd t5, binfo(t1) # update size sd t5, binfo(t1) # update size
sd t3, fb_next(t1) # update next (for case 3) sd t3, fb_next(t1) # update next (for 3b)
0: 0:
# step 2: # step 2:
@@ -169,7 +174,7 @@ heap_alloc:
li t4, sizeof_fb li t4, sizeof_fb
bltu t5, t4, 0f # check if enough for a free block bltu t5, t4, 0f # check if enough for a free block
# add free block at end if space # add free block at end of space
add t3, t1, t0 # if so, get addr (t3) add t3, t1, t0 # if so, get addr (t3)
sd t3, fb_next(t6) # set prev block next to new sd t3, fb_next(t6) # set prev block next to new
@@ -179,6 +184,7 @@ heap_alloc:
sd t6, binfo(t3) sd t6, binfo(t3)
ld t6, fb_next(t1) # copy next ld t6, fb_next(t1) # copy next
sd t6, fb_next(t3) sd t6, fb_next(t3)
sd t3, fb_prev(t6) # set next block prev to new
move t5, t3 move t5, t3
j 1f j 1f
@@ -188,17 +194,18 @@ heap_alloc:
move t0, t2 move t0, t2
ld t4, fb_next(t1) ld t4, fb_next(t1)
sd t4, fb_next(t6) # set prev next to cur next sd t4, fb_next(t6) # set prev next to cur next
sd t6, fb_prev(t4) # set next prev to cur prev
ld t4, heap_end(t3) ld t4, heap_end(t3)
add t5, t1, t0 add t5, t1, t0
bne t5, t4, 1f # if this is at the end bne t5, t4, 1f # if this is at the end
move t5, t3 # select the heap info for next move t5, t3 # select the heap info for next
1:
# update next's prev used # update next's prev used
ld t4, binfo(t5) ld t4, binfo(t5)
ori t4, t4, prev_used ori t4, t4, prev_used
sd t4, binfo(t5) sd t4, binfo(t5)
1:
# step 3: # step 3:
# create used block # create used block
@@ -220,11 +227,14 @@ heap_alloc:
# a0 - address # a0 - address
.global heap_free .global heap_free
heap_free: heap_free:
addi a0, a0, -8 # get actual block addr
ld t2, binfo(a0) ld t2, binfo(a0)
andi t0, t2, size_mask # t0 = size andi t0, t2, size_mask # t0 = size
la t3, heap_info # t3 = heap info la t3, heap_info # t3 = heap info
sd t4, heap_end(t3) # t4 = heap end ld t4, heap_end(t3) # t4 = heap end
li t5, 0 # merged flag
# step 1: # step 1:
# merge with prev if possible # merge with prev if possible
@@ -235,6 +245,7 @@ heap_free:
ld t2, binfo(a0) ld t2, binfo(a0)
andi t1, t2, size_mask # t1 = prev size andi t1, t2, size_mask # t1 = prev size
add t0, t0, t1 # add to size add t0, t0, t1 # add to size
li t5, 1 # set merged flag
0: 0:
# step 2: # step 2:
@@ -244,17 +255,28 @@ heap_free:
bge t2, t4, 0f # skip if end bge t2, t4, 0f # skip if end
ld t1, binfo(t2) ld t1, binfo(t2)
andi t1, t1, size_mask # t1 = next size andi t1, t1, size_mask # t1 = next size
add t2, t2, t1 # t2 = next next block add t6, t2, t1 # t6 = next next block
blt t2, t4, 1f # if end: blt t6, t4, 1f # if end:
ld t2, binfo(t3) # t2 = last block is used ld t6, binfo(t3) # t6 = last block is used
bnez t2, 0f # skip if used bnez t6, 0f # skip if used
j 2f # if end free, we can use j 2f # if end free, we can use
1: # if not end: 1: # if not end:
ld t2, binfo(t2) ld t6, binfo(t6)
andi t2, t2, prev_used # t2 = next used (n->n->pu) andi t6, t6, prev_used # t6 = next is used (n->n->pu)
bnez t2, 0f # skip if used bnez t6, 0f # skip if used
2: # as long as not skipped: 2: # as long as not skipped:
add t0, t0, t1 # add to size add t0, t0, t1 # add to size
ld t6, fb_next(t2)
sd t6, fb_next(a0) # update our next
sd a0, fb_prev(t6) # update next next's prev
bnez t5, 3f # if not merged:
ld t6, fb_prev(t2)
sd t6, fb_prev(a0) # update our prev
sd a0, fb_next(t6) # update prev's next
3:
li t5, 1 # set merged flag
0: 0:
# step 3: # step 3:
@@ -262,9 +284,14 @@ heap_free:
ori t1, t0, prev_used # set prev used ori t1, t0, prev_used # set prev used
sd t1, binfo(a0) # store info sd t1, binfo(a0) # store info
ld t2, fb_next(t3) # insert at head of free list
sd t2, fb_next(a0) bnez t5, 0f # skip insertion if merged
sd a0, fb_next(t3) ld t2, fb_next(t3) # insert at head of free list:
sd t2, fb_next(a0) # this next
sd a0, fb_next(t3) # table next
sd a0, fb_prev(t2) # next prev
sd t3, fb_prev(a0) # this prev
0:
add t1, a0, t0 # get next addr add t1, a0, t0 # get next addr
sd a0, -8(t1) # store addr at end sd a0, -8(t1) # store addr at end
@@ -272,7 +299,12 @@ heap_free:
bne t1, t4, 0f # if end bne t1, t4, 0f # if end
li t1, 0 # unset heap end used li t1, 0 # unset heap end used
sd t1, binfo(t3) sd t1, binfo(t3)
0: j 1f
0: # if not end
ld t2, binfo(t1) # unset next prev used
andi t2, t2, ~prev_used
sd t2, binfo(t1)
1:
ret ret

View File

@@ -27,10 +27,14 @@ hexstr:
.global heap_test .global heap_test
heap_test: heap_test:
addi sp, sp, -(3*8) addi sp, sp, -(7*8)
sd ra, 0(sp) sd ra, 0(sp)
sd s0, 8(sp) sd s0, 8(sp)
sd s1, 16(sp) sd s1, 16(sp)
sd s2, 24(sp)
sd s3, 32(sp)
sd s4, 40(sp)
sd s5, 48(sp)
# empty heap # empty heap
@@ -41,7 +45,10 @@ heap_test:
li a0, 8*9 li a0, 8*9
jal heap_alloc jal heap_alloc
move s2, a0
jal print_heap
jal printnl
li a0, 8*4 li a0, 8*4
jal heap_alloc jal heap_alloc
@@ -49,8 +56,11 @@ heap_test:
sd t0, (a0) sd t0, (a0)
sd t0, 8(a0) sd t0, 8(a0)
sd t0, 24(a0) sd t0, 24(a0)
move s3, a0
li s0, 0x0f # put array of stuff on heap
li s0, 0x0a
0: 0:
bltz s0, 0f bltz s0, 0f
@@ -69,56 +79,54 @@ heap_test:
jal heap_alloc jal heap_alloc
li t0, 0xffff li t0, 0xffff
sd t0, 6*8(a0) sd t0, 6*8(a0)
move s5, a0
li a0, 8*3 li a0, 8*3
jal heap_alloc jal heap_alloc
move s4, a0
jal print_heap
jal printnl
# free stuff
move a0, s2
jal heap_free
move a0, s3
jal heap_free
move a0, s4
jal heap_free
move a0, s5
jal heap_free
jal print_heap jal print_heap
ld ra, 0(sp) ld ra, 0(sp)
ld s0, 8(sp) ld s0, 8(sp)
ld s1, 16(sp) ld s1, 16(sp)
addi sp, sp, +(3*8) sd s2, 24(sp)
sd s3, 32(sp)
sd s4, 40(sp)
sd s5, 48(sp)
addi sp, sp, +(7*8)
ret ret
print_heap: print_heap:
addi sp, sp, -(4*8) addi sp, sp, -8
sd ra, 0(sp)
jal print_heap_info
jal print_heap_blocks
ld ra, 0(sp)
addi sp, sp, +8
ret
print_heap_blocks:
addi sp, sp, -(3*8)
sd ra, 0(sp) sd ra, 0(sp)
sd s0, 8(sp) sd s0, 8(sp)
sd s1, 16(sp) sd s1, 16(sp)
sd s2, 24(sp)
# info
la a0, hinfo_msg
lw a1, -4(a0)
jal print
jal print_space
la a0, hexstr
lw a1, -4(a0)
jal print
la s0, heap_info
move a0, s0
jal print_hex
jal printnl
li s1, 0
li s2, 4
0:
beq s1, s2, 0f
jal print_space
jal print_space
li t1, 8
mul t0, s1, t1
add t0, s0, t0
ld a0, 0(t0)
jal print_hex
jal printnl
addi s1, s1, 1
j 0b
0:
# blocks # blocks
@@ -127,8 +135,8 @@ print_heap:
jal println jal println
la t0, heap_info la t0, heap_info
ld s0, 16(t0) ld s0, 24(t0)
ld s1, 24(t0) ld s1, 32(t0)
0: 0:
jal print_space jal print_space
jal print_space jal print_space
@@ -144,10 +152,20 @@ print_heap:
jal print_hex jal print_hex
jal print_space jal print_space
jal printnl
jal print_space
jal print_space
jal print_space
jal print_space
ld a0, 8(s0) ld a0, 8(s0)
jal print_hex jal print_hex
jal print_space jal print_space
ld a0, 16(s0)
jal print_hex
jal print_space
la a0, dots la a0, dots
lw a1, -4(a0) lw a1, -4(a0)
jal print jal print
@@ -165,6 +183,49 @@ print_heap:
j 0b j 0b
0: 0:
ld ra, 0(sp)
ld s0, 8(sp)
ld s1, 16(sp)
addi sp, sp, +(3*8)
ret
print_heap_info:
addi sp, sp, -(4*8)
sd ra, 0(sp)
sd s0, 8(sp)
sd s1, 16(sp)
sd s2, 24(sp)
la a0, hinfo_msg
lw a1, -4(a0)
jal print
jal print_space
la a0, hexstr
lw a1, -4(a0)
jal print
la s0, heap_info
move a0, s0
jal print_hex
jal printnl
li s1, 0
li s2, 5
0:
beq s1, s2, 0f
jal print_space
jal print_space
li t1, 8
mul t0, s1, t1
add t0, s0, t0
ld a0, 0(t0)
jal print_hex
jal printnl
addi s1, s1, 1
j 0b
0:
ld ra, 0(sp) ld ra, 0(sp)
ld s0, 8(sp) ld s0, 8(sp)
ld s1, 16(sp) ld s1, 16(sp)