From 77e3ff1b361bd7a776e47a4932886f1a77c8d2ac Mon Sep 17 00:00:00 2001 From: Bryan McShea Date: Tue, 18 Oct 2022 01:22:16 -0400 Subject: [PATCH] so I added free, no idea if it works because I need to start hw :skull: --- src/lib/heap.s | 87 ++++++++++++++++++++++++++++++++++++++++--------- src/test/heap.s | 4 +++ 2 files changed, 76 insertions(+), 15 deletions(-) diff --git a/src/lib/heap.s b/src/lib/heap.s index 34967b0..50a55b9 100644 --- a/src/lib/heap.s +++ b/src/lib/heap.s @@ -12,7 +12,7 @@ # block node -.equ bsize, 0 +.equ binfo, 0 .equ fb_next, 8 # free only # free also contains its address at the end @@ -37,7 +37,8 @@ heap_oom: .align 4 .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_start, 16 .equ heap_end, 24 @@ -88,7 +89,7 @@ heap_init: # create initial free block 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 t1, -8(a0) # store addr at end @@ -115,8 +116,9 @@ heap_alloc: addi t0, t0, align_imask andi t0, t0, align_mask + # step 1: # get a free block that will fit (t1) - # and its free space + # and its free space (t2) la t3, heap_info ld t4, heap_first_free(t3) @@ -131,8 +133,10 @@ heap_alloc: move t1, t4 # current block (t1) + # loop through free blocks + 0: - ld t2, bsize(t1) # size of current block (t2) + ld t2, binfo(t1) # size of current block (t2) andi t2, t2, size_mask bgeu t2, t0, 0f # is it big enough ld t5, fb_next(t1) # if not, get the next @@ -140,7 +144,9 @@ heap_alloc: move t6, t1 move t1, t5 j 0b + 1: # if no blocks are big enough + add t5, t1, t2 # get end of last free block beq t5, a1, 2f # if no free block at end of heap: move t6, t1 @@ -152,10 +158,11 @@ heap_alloc: sd a0, heap_end(t3) # update end in info sub t2, a0, t1 # new free space (t2) 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) 0: + # step 2: # deal with extra free space sub t5, t2, t0 # unneeded free space (t5) @@ -167,27 +174,30 @@ heap_alloc: add t6, t3, t5 # store addr at end sd t3, -8(t6) 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 sd t6, fb_next(t3) + move t5, t3 j 1f -0: - move t0, t2 # if no space, fill in with used +0: # if no space, fill in with used + move t0, t2 ld t4, fb_next(t1) sd t4, fb_next(t6) # set prev next to cur next ld t4, heap_end(t3) - add t3, t1, t0 - beq t3, t4, 1f # if this is not at the end - ld t4, bsize(t3) # set next's prev used to 1 + add t5, t1, t0 + bne t5, t4, 1f # if this is at the end + 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 - sd t4, bsize(t3) -1: + sd t4, binfo(t5) + # step 3: # create used block add t2, t0, t1 # end of block 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, -8(t2) @@ -202,6 +212,53 @@ heap_alloc: # a0 - address .global 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 # args: diff --git a/src/test/heap.s b/src/test/heap.s index 8fc6b81..cb71ef5 100644 --- a/src/test/heap.s +++ b/src/test/heap.s @@ -39,6 +39,10 @@ heap_test: # put stuff on heap + li a0, 8*9 + jal heap_alloc + + li a0, 8*4 jal heap_alloc li t0, 0x1111111111111111