so I added free, no idea if it works because I need to start hw 💀
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
# block node
|
# block node
|
||||||
|
|
||||||
.equ bsize, 0
|
.equ binfo, 0
|
||||||
.equ fb_next, 8 # free only
|
.equ fb_next, 8 # free only
|
||||||
# free also contains its address at the end
|
# free also contains its address at the end
|
||||||
|
|
||||||
@@ -37,7 +37,8 @@ heap_oom:
|
|||||||
|
|
||||||
.align 4
|
.align 4
|
||||||
.global heap_info # global for testing only
|
.global heap_info # global for testing only
|
||||||
.equ heap_last_used, 0 # last free block will set this
|
.equ heap_last_used, 0 # is the last block used;
|
||||||
|
# matches binfo
|
||||||
.equ heap_first_free, 8 # matches fb_next
|
.equ heap_first_free, 8 # matches fb_next
|
||||||
.equ heap_start, 16
|
.equ heap_start, 16
|
||||||
.equ heap_end, 24
|
.equ heap_end, 24
|
||||||
@@ -88,7 +89,7 @@ heap_init:
|
|||||||
# create initial free block
|
# create initial free block
|
||||||
|
|
||||||
ori t2, t2, prev_used # add prev used
|
ori t2, t2, prev_used # add prev used
|
||||||
sd t2, bsize(t1) # store size
|
sd t2, binfo(t1) # store size
|
||||||
sd t0, fb_next(t1) # store next
|
sd t0, fb_next(t1) # store next
|
||||||
sd t1, -8(a0) # store addr at end
|
sd t1, -8(a0) # store addr at end
|
||||||
|
|
||||||
@@ -115,8 +116,9 @@ heap_alloc:
|
|||||||
addi t0, t0, align_imask
|
addi t0, t0, align_imask
|
||||||
andi t0, t0, align_mask
|
andi t0, t0, align_mask
|
||||||
|
|
||||||
|
# step 1:
|
||||||
# get a free block that will fit (t1)
|
# get a free block that will fit (t1)
|
||||||
# and its free space
|
# and its free space (t2)
|
||||||
|
|
||||||
la t3, heap_info
|
la t3, heap_info
|
||||||
ld t4, heap_first_free(t3)
|
ld t4, heap_first_free(t3)
|
||||||
@@ -131,8 +133,10 @@ heap_alloc:
|
|||||||
|
|
||||||
move t1, t4 # current block (t1)
|
move t1, t4 # current block (t1)
|
||||||
|
|
||||||
|
# loop through free blocks
|
||||||
|
|
||||||
0:
|
0:
|
||||||
ld t2, bsize(t1) # size of current block (t2)
|
ld t2, binfo(t1) # size of current block (t2)
|
||||||
andi t2, t2, size_mask
|
andi t2, t2, size_mask
|
||||||
bgeu t2, t0, 0f # is it big enough
|
bgeu t2, t0, 0f # is it big enough
|
||||||
ld t5, fb_next(t1) # if not, get the next
|
ld t5, fb_next(t1) # if not, get the next
|
||||||
@@ -140,7 +144,9 @@ heap_alloc:
|
|||||||
move t6, t1
|
move t6, t1
|
||||||
move t1, t5
|
move t1, t5
|
||||||
j 0b
|
j 0b
|
||||||
|
|
||||||
1: # if no blocks are big enough
|
1: # if no blocks are big enough
|
||||||
|
|
||||||
add t5, t1, t2 # get end of last free block
|
add t5, t1, t2 # get end of last free block
|
||||||
beq t5, a1, 2f # if no free block at end of heap:
|
beq t5, a1, 2f # if no free block at end of heap:
|
||||||
move t6, t1
|
move t6, t1
|
||||||
@@ -152,10 +158,11 @@ heap_alloc:
|
|||||||
sd a0, heap_end(t3) # update end in info
|
sd a0, heap_end(t3) # update end in info
|
||||||
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, bsize(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 case 3)
|
||||||
0:
|
0:
|
||||||
|
|
||||||
|
# step 2:
|
||||||
# deal with extra free space
|
# deal with extra free space
|
||||||
|
|
||||||
sub t5, t2, t0 # unneeded free space (t5)
|
sub t5, t2, t0 # unneeded free space (t5)
|
||||||
@@ -167,27 +174,30 @@ heap_alloc:
|
|||||||
add t6, t3, t5 # store addr at end
|
add t6, t3, t5 # store addr at end
|
||||||
sd t3, -8(t6)
|
sd t3, -8(t6)
|
||||||
ori t6, t5, prev_used # store size with prev in use
|
ori t6, t5, prev_used # store size with prev in use
|
||||||
sd t6, bsize(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)
|
||||||
|
move t5, t3
|
||||||
j 1f
|
j 1f
|
||||||
0:
|
0: # if no space, fill in with used
|
||||||
move t0, t2 # if no space, fill in with used
|
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
|
||||||
ld t4, heap_end(t3)
|
ld t4, heap_end(t3)
|
||||||
add t3, t1, t0
|
add t5, t1, t0
|
||||||
beq t3, t4, 1f # if this is not at the end
|
bne t5, t4, 1f # if this is at the end
|
||||||
ld t4, bsize(t3) # set next's prev used to 1
|
move t5, t3 # select the heap info for next
|
||||||
|
1: # either way
|
||||||
|
ld t4, binfo(t5) # set next's prev used to 1
|
||||||
ori t4, t4, prev_used
|
ori t4, t4, prev_used
|
||||||
sd t4, bsize(t3)
|
sd t4, binfo(t5)
|
||||||
1:
|
|
||||||
|
|
||||||
|
# step 3:
|
||||||
# create used block
|
# create used block
|
||||||
|
|
||||||
add t2, t0, t1 # end of block
|
add t2, t0, t1 # end of block
|
||||||
ori t0, t0, prev_used # prev used bit
|
ori t0, t0, prev_used # prev used bit
|
||||||
sd t0, bsize(t1) # store size
|
sd t0, binfo(t1) # store size
|
||||||
sd zero, fb_next(t1) # remove free block stuff
|
sd zero, fb_next(t1) # remove free block stuff
|
||||||
sd zero, -8(t2)
|
sd zero, -8(t2)
|
||||||
|
|
||||||
@@ -202,6 +212,53 @@ heap_alloc:
|
|||||||
# a0 - address
|
# a0 - address
|
||||||
.global heap_free
|
.global heap_free
|
||||||
heap_free:
|
heap_free:
|
||||||
|
ld t2, binfo(a0)
|
||||||
|
andi t0, t2, size_mask # t0 = size
|
||||||
|
|
||||||
|
la t3, heap_info # t3 = heap info
|
||||||
|
sd t4, heap_end(t3) # t4 = heap end
|
||||||
|
|
||||||
|
# step 1:
|
||||||
|
# merge with prev if possible
|
||||||
|
|
||||||
|
andi t1, t2, prev_used # t1 = prev used
|
||||||
|
bnez t1, 0f # if prev not used:
|
||||||
|
ld a0, -8(a0) # a0 = prev block addr
|
||||||
|
ld t2, binfo(a0)
|
||||||
|
andi t1, t2, size_mask # t1 = prev size
|
||||||
|
add t0, t0, t1 # add to size
|
||||||
|
0:
|
||||||
|
|
||||||
|
# step 2:
|
||||||
|
# merge with next if possible
|
||||||
|
|
||||||
|
add t2, a0, t0 # t2 = next block
|
||||||
|
bge t2, t4, 0f # skip if end
|
||||||
|
ld t1, binfo(t2)
|
||||||
|
andi t1, t1, size_mask # t1 = next size
|
||||||
|
add t2, t2, t1 # t2 = next next block
|
||||||
|
blt t2, t4, 1f # if end:
|
||||||
|
ld t2, binfo(t3) # t2 = last block is used
|
||||||
|
bnez t2, 0f # skip if used
|
||||||
|
j 2f # if end free, we can use
|
||||||
|
1: # if not end:
|
||||||
|
ld t2, binfo(t2)
|
||||||
|
andi t2, t2, prev_used # t2 = next used (n->n->pu)
|
||||||
|
bnez t2, 0f # if next not used:
|
||||||
|
2: # as long as not skipped:
|
||||||
|
add t0, t0, t1 # add to size
|
||||||
|
0:
|
||||||
|
|
||||||
|
# step 3:
|
||||||
|
# write block
|
||||||
|
|
||||||
|
ori t1, t0, prev_used # set prev used
|
||||||
|
sd t1, binfo(a0) # store info
|
||||||
|
ld t2, fb_next(t3) # insert at head of free list
|
||||||
|
sd t2, fb_next(a0)
|
||||||
|
sd a0, fb_next(t3)
|
||||||
|
add t1, a0, t0 # get next addr
|
||||||
|
sd a0, -8(t1) # store addr at end
|
||||||
ret
|
ret
|
||||||
|
|
||||||
# args:
|
# args:
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ heap_test:
|
|||||||
|
|
||||||
# put stuff on heap
|
# put stuff on heap
|
||||||
|
|
||||||
|
li a0, 8*9
|
||||||
|
jal heap_alloc
|
||||||
|
|
||||||
|
|
||||||
li a0, 8*4
|
li a0, 8*4
|
||||||
jal heap_alloc
|
jal heap_alloc
|
||||||
li t0, 0x1111111111111111
|
li t0, 0x1111111111111111
|
||||||
|
|||||||
Reference in New Issue
Block a user