feat: implemented realloc
This commit is contained in:
parent
73f577fb7a
commit
960b2aee42
|
@ -3,16 +3,12 @@
|
|||
|
||||
int main(int argc, char const *argv[]) {
|
||||
sf_set_magic(0x0);
|
||||
double* ptr = sf_malloc(sizeof(double));
|
||||
size_t sz_x = 8, sz_y = 200, sz_z = 1;
|
||||
/* void *x = */ sf_malloc(sz_x);
|
||||
void *y = sf_malloc(sz_y);
|
||||
/* void *z = */ sf_malloc(sz_z);
|
||||
|
||||
*ptr = 114514;
|
||||
|
||||
printf("%f\n", *ptr);
|
||||
|
||||
sf_free(ptr);
|
||||
|
||||
sf_show_heap();
|
||||
sf_show_free_lists();
|
||||
sf_free(y);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ sf_size_t get_size_of_index(sf_size_t index);
|
|||
sf_block *split_block(sf_block *block, size_t size);
|
||||
void valid_pointer(sf_block *pp);
|
||||
void release_block(sf_block *block);
|
||||
sf_block *get_prev_block(sf_block *block);
|
||||
sf_block *get_next_block(sf_block *block);
|
||||
|
||||
void *sf_malloc(sf_size_t size)
|
||||
{
|
||||
|
@ -56,6 +58,7 @@ void *sf_malloc(sf_size_t size)
|
|||
sf_block *block = sf_quick_lists[index].first;
|
||||
sf_quick_lists[index].length -= 1;
|
||||
sf_quick_lists[index].first = block->body.links.next;
|
||||
set_entire_header(block, size, get_block_size(block->header), 1, get_prv_alloc(block->header), 0);
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -71,7 +74,7 @@ void *sf_malloc(sf_size_t size)
|
|||
{
|
||||
if (get_block_size(ptr->header) >= min_size)
|
||||
{
|
||||
set_entire_header(ptr, size, get_block_size(ptr->header), 1, 0, 0);
|
||||
set_entire_header(ptr, size, get_block_size(ptr->header), 1, get_prv_alloc(ptr->header), 0);
|
||||
return ptr->body.payload;
|
||||
}
|
||||
}
|
||||
|
@ -84,22 +87,38 @@ void *sf_malloc(sf_size_t size)
|
|||
{
|
||||
sf_block *block = split_block(ptr, min_size);
|
||||
sf_size_t block_size = get_block_size(block->header);
|
||||
set_entire_header(block, size, block_size, 1, 0, 0);
|
||||
sf_show_block(block);
|
||||
sf_show_block(ptr);
|
||||
set_entire_header(block, size, block_size, 1, get_prv_alloc(block->header), 0);
|
||||
return block->body.payload;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TO BE IMPLEMENTED
|
||||
return NULL;
|
||||
sf_block *last = get_prev_block(epi);
|
||||
if (get_alloc(last->header) == 1)
|
||||
last = epi;
|
||||
sf_size_t require_size = min_size - get_block_size(last->header);
|
||||
size_t i = 0;
|
||||
for (; i < require_size; i += 1024)
|
||||
{
|
||||
if (sf_mem_grow() == NULL)
|
||||
{
|
||||
sf_errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
set_entire_header(last, 0, (get_block_size(last->header) + i), 0, get_prv_alloc(last->header), 0);
|
||||
sf_block *ptr = split_block(last, min_size);
|
||||
put_block(last);
|
||||
set_entire_header(ptr, size, get_block_size(ptr->header), 1, 0, 0);
|
||||
epi = (sf_block *)(((intptr_t)sf_mem_end()) - 2 * sizeof(sf_header));
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void sf_free(void *pp)
|
||||
{
|
||||
sf_block *block = (sf_block *)(intptr_t)(pp - 2 * sizeof(sf_header));
|
||||
sf_block *block = (sf_block *)(((intptr_t)pp) - 2 * sizeof(sf_header));
|
||||
valid_pointer(block);
|
||||
|
||||
sf_size_t index = (get_block_size(block->header) - 32) / 16;
|
||||
|
@ -128,8 +147,29 @@ void sf_free(void *pp)
|
|||
|
||||
void *sf_realloc(void *pp, sf_size_t rsize)
|
||||
{
|
||||
// TO BE IMPLEMENTED
|
||||
abort();
|
||||
sf_block *block = (sf_block *)(((intptr_t)pp) - 2 * sizeof(sf_header));
|
||||
valid_pointer(block);
|
||||
sf_size_t size = get_block_size(block->header);
|
||||
sf_size_t new_size = get_min_size(size);
|
||||
if (new_size >= size)
|
||||
{
|
||||
sf_block *new = sf_malloc(rsize);
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
memcpy(new->body.payload, block->body.payload, size);
|
||||
sf_free(block);
|
||||
return new->body.payload;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size - new_size < min)
|
||||
return block->body.payload;
|
||||
else {
|
||||
sf_block *ptr = split_block(block, (size - new_size));
|
||||
put_block(ptr);
|
||||
return block->body.payload;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double sf_internal_fragmentation()
|
||||
|
@ -152,8 +192,8 @@ int sf_initialize()
|
|||
return 1;
|
||||
}
|
||||
pro = (sf_block *)sf_mem_start();
|
||||
set_entire_header(pro, 0, 32, 1, 0, 0);
|
||||
epi = (sf_block *)((intptr_t)sf_mem_end() - 2 * sizeof(sf_header));
|
||||
set_entire_header(pro, 0, 32, 1, 1, 0);
|
||||
epi = (sf_block *)(((intptr_t)sf_mem_end()) - 2 * sizeof(sf_header));
|
||||
set_entire_header(epi, 0, 0, 1, 1, 0);
|
||||
for (size_t i = 0; i < NUM_FREE_LISTS; i++)
|
||||
{
|
||||
|
@ -165,9 +205,10 @@ int sf_initialize()
|
|||
sf_quick_lists[i].length = 0;
|
||||
sf_quick_lists[i].first = NULL;
|
||||
}
|
||||
sf_block *block = (sf_block *)((intptr_t)sf_mem_start() + 4 * sizeof(sf_header));
|
||||
sf_block *block = get_next_block(pro);
|
||||
sf_size_t size = PAGE_SZ - 6 * sizeof(sf_header);
|
||||
set_entire_header(block, 0, size, 0, 1, 0);
|
||||
block->prev_footer = pro->header;
|
||||
put_block(block);
|
||||
return 0;
|
||||
}
|
||||
|
@ -185,7 +226,7 @@ void set_header(sf_block *block, sf_header value)
|
|||
block->header = value;
|
||||
if (get_alloc(block->header) == 0)
|
||||
{
|
||||
sf_block *next = (sf_block *)((intptr_t)block + get_block_size(block->header));
|
||||
sf_block *next = get_next_block(block);
|
||||
next->prev_footer = block->header;
|
||||
}
|
||||
}
|
||||
|
@ -309,8 +350,8 @@ sf_block *split_block(sf_block *block, size_t size)
|
|||
size_t original_size = get_block_size(block->header);
|
||||
size_t new_size = original_size - size;
|
||||
set_block_size(block, new_size);
|
||||
sf_block *ptr = (sf_block *)((intptr_t)block + get_block_size(block->header));
|
||||
set_entire_header(ptr, 0, size, 0, 0, 0);
|
||||
sf_block *ptr = get_next_block(block);
|
||||
set_entire_header(ptr, 0, size, 0, get_prv_alloc(block->header), 0);
|
||||
ptr->prev_footer = block->header;
|
||||
return ptr;
|
||||
}
|
||||
|
@ -322,7 +363,7 @@ void valid_pointer(sf_block *pp)
|
|||
// pp->header ^= sf_magic();
|
||||
if (get_block_size(pp->header) < 32 || get_block_size(pp->header) % 16 != 0)
|
||||
abort();
|
||||
if ((intptr_t)&pp->header < ((intptr_t)&pro->header + 32) || (intptr_t)&pp->header > ((intptr_t)&epi->header - 8))
|
||||
if (((intptr_t)&pp->header) < (((intptr_t)&pro->header) + 32) || ((intptr_t)&pp->header) > (((intptr_t)&epi->header) - 8))
|
||||
abort();
|
||||
if (get_alloc(pp->header) == 0 || (get_prv_alloc(pp->header) == 0 && get_alloc(pp->prev_footer) != 0))
|
||||
abort();
|
||||
|
@ -331,16 +372,16 @@ void valid_pointer(sf_block *pp)
|
|||
|
||||
void release_block(sf_block *block)
|
||||
{
|
||||
sf_block *next = (sf_block *)((intptr_t)block + get_block_size(block->header));
|
||||
sf_block *prev = (sf_block *)((intptr_t)block - get_block_size(block->prev_footer));
|
||||
sf_block *next = get_next_block(block);
|
||||
sf_block *prev = get_prev_block(block);
|
||||
sf_size_t total_size = get_block_size(block->header);
|
||||
if (get_alloc(next->header) == 0)
|
||||
if (next != epi && get_alloc(next->header) == 0)
|
||||
{
|
||||
next->body.links.prev->body.links.next = next->body.links.next;
|
||||
next->body.links.next->body.links.prev = next->body.links.prev;
|
||||
total_size += get_block_size(next->header);
|
||||
}
|
||||
if (get_alloc(block->prev_footer) == 0)
|
||||
if (prev != pro && get_alloc(prev->header) == 0)
|
||||
{
|
||||
prev->body.links.prev->body.links.next = prev->body.links.next;
|
||||
prev->body.links.next->body.links.prev = prev->body.links.prev;
|
||||
|
@ -351,3 +392,13 @@ void release_block(sf_block *block)
|
|||
put_block(block);
|
||||
return;
|
||||
}
|
||||
|
||||
sf_block *get_prev_block(sf_block *block)
|
||||
{
|
||||
return (sf_block *)(((intptr_t)block) - get_block_size(block->prev_footer));
|
||||
}
|
||||
|
||||
sf_block *get_next_block(sf_block *block)
|
||||
{
|
||||
return (sf_block *)(((intptr_t)block) + get_block_size(block->header));
|
||||
}
|
Loading…
Reference in New Issue
Block a user