salloc test cases added and passed.

This commit is contained in:
secXsQuared 2016-05-24 00:10:32 -07:00
parent bd204b40f2
commit 0c48e9fa1c
6 changed files with 381 additions and 92 deletions

View File

@ -8,7 +8,7 @@ typedef struct _avl_tree_node_t
struct _avl_tree_node_t *left;
struct _avl_tree_node_t *right;
struct _avl_tree_node_t *parent;
int height;
int32_t height;
} avl_tree_node_t;
typedef struct

View File

@ -3,10 +3,13 @@
#include "k_def.h"
void salloc_init(void *base, uint32_t size);
void SAPI salloc_init(void *base, uint32_t size);
void* salloc(void *base, uint32_t size);
void* SAPI salloc(void *base, uint32_t size);
void SAPI sfree(void *base, void *ptr);
bool SAPI salloc_assert(void *base, uint32_t blk_size[], bool blk_free[], uint32_t size);
void sfree(void *base, void *ptr);
#endif

View File

@ -1,17 +1,17 @@
#include "k_def.h"
#include "bit_ops.h"
typedef union {
typedef union
{
uint32_t size;
uint32_t flags;
} alloc_header;
} _salloc_header;
#define ALLOC_FLAG_NUM 2
#define ALLOC_HEADER_FLAG_FREE 0
#define ALLOC_HEADER_FLAG_LAST 1
static void SAPI _set_alloc_header_size(alloc_header *header, uint32_t size)
static void _set_salloc_header_size(_salloc_header *header, uint32_t size)
{
// align the integer, ignoring overflowed bits
size <<= ALLOC_FLAG_NUM;
@ -23,20 +23,20 @@ static void SAPI _set_alloc_header_size(alloc_header *header, uint32_t size)
return;
}
static uint32_t SAPI _read_alloc_header_size(alloc_header *header)
static uint32_t _read_salloc_header_size(_salloc_header *header)
{
return header->size >> ALLOC_FLAG_NUM;
}
static uint32_t SAPI _read_alloc_header_flag(alloc_header *header, uint32_t bit)
static uint32_t _read_salloc_header_flag(_salloc_header *header, uint32_t bit)
{
return (header->flags & bit_mask_32(bit)) == 0 ? 0 : 1;
}
static void SAPI _set_alloc_header_flag(alloc_header *header, uint32_t bit, uint32_t value)
static void _set_salloc_header_flag(_salloc_header *header, uint32_t bit, uint32_t value)
{
value &= bit_mask_32(0);
if(value == 1)
if (value == 1)
{
header->flags |= bit_mask_32(bit);
}
@ -47,34 +47,34 @@ static void SAPI _set_alloc_header_flag(alloc_header *header, uint32_t bit, uint
return;
}
static void _alloc_join(void *base)
static void _salloc_join(void *base)
{
if(base != NULL)
if (base != NULL)
{
char* c_ptr = (char*)base;
while(1)
char *c_ptr = (char *) base;
while (1)
{
uint32_t c_blk_free = _read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t c_blk_last = _read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t c_blk_size = _read_alloc_header_size((alloc_header *) c_ptr);
char* n_ptr = c_blk_last == 1 ? NULL : c_ptr + c_blk_size;
if(n_ptr != NULL && c_blk_free == 1)
uint32_t c_blk_free = _read_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t c_blk_last = _read_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t c_blk_size = _read_salloc_header_size((_salloc_header *) c_ptr);
char *n_ptr = c_blk_last == 1 ? NULL : c_ptr + c_blk_size;
if (n_ptr != NULL && c_blk_free == 1)
{
// if this is not the last block and the prev block is free
uint32_t n_blk_free = _read_alloc_header_flag((alloc_header *) n_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t n_blk_last = _read_alloc_header_flag((alloc_header *) n_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t n_blk_size = _read_alloc_header_size((alloc_header *) n_ptr);
uint32_t n_blk_free = _read_salloc_header_flag((_salloc_header *) n_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t n_blk_last = _read_salloc_header_flag((_salloc_header *) n_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t n_blk_size = _read_salloc_header_size((_salloc_header *) n_ptr);
if (n_blk_free == 1)
{
// logically gone
_set_alloc_header_size((alloc_header *) c_ptr, n_blk_size + c_blk_size);
_set_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, n_blk_last);
_set_salloc_header_size((_salloc_header *) c_ptr, n_blk_size + c_blk_size);
_set_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, n_blk_last);
continue;
}
}
// update the c_ptr
if(c_blk_last == 0)
if (c_blk_last == 0)
{
c_ptr += c_blk_size;
}
@ -86,61 +86,62 @@ static void _alloc_join(void *base)
}
}
//static void salloc_print(void* base)
//{
// if(base != NULL)
// {
// //printf("=======================================================\n");
// char* c_ptr = (char*)base;
// while(1)
// {
// uint32_t cur_blk_free = _read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
// uint32_t cur_blk_last = _read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
// uint32_t cur_blk_size = _read_alloc_header_size((alloc_header *) c_ptr);
// //printf("Block:0x%llX Size:%d Free:%d Last:%d\n", (unsigned long long)c_ptr, cur_blk_size, cur_blk_free, cur_blk_last);
//
// if(cur_blk_last == 1)
// {
// break;
// }
// else
// {
// c_ptr += cur_blk_size;
// }
// }
// }
// return;
//}
void salloc_init(void *base, uint32_t size)
bool SAPI salloc_assert(void *base, uint32_t blk_size[], bool blk_free[], uint32_t size)
{
if(base != NULL && size >= sizeof(alloc_header))
if (base == NULL || blk_free == NULL || blk_size == NULL)
return NULL;
uint32_t i = 0;
char *c_ptr = (char *) base;
while (1)
{
alloc_header* ptr = (alloc_header*)base;
_set_alloc_header_size(ptr, size);
_set_alloc_header_flag(ptr, ALLOC_HEADER_FLAG_FREE, 1);
_set_alloc_header_flag(ptr, ALLOC_HEADER_FLAG_LAST, 1);
uint32_t cur_blk_free = _read_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t cur_blk_last = _read_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t cur_blk_size = _read_salloc_header_size((_salloc_header *) c_ptr);
if (cur_blk_free != blk_free[i] || cur_blk_size != blk_size[i])
{
return false;
}
else
{
c_ptr += cur_blk_size;
i++;
}
if (cur_blk_last == 1)
{
return i == size;
}
}
}
void SAPI salloc_init(void *base, uint32_t size)
{
if (base != NULL && size >= sizeof(_salloc_header))
{
_salloc_header *ptr = (_salloc_header *) base;
_set_salloc_header_size(ptr, size);
_set_salloc_header_flag(ptr, ALLOC_HEADER_FLAG_FREE, 1);
_set_salloc_header_flag(ptr, ALLOC_HEADER_FLAG_LAST, 1);
}
return;
}
void* salloc(void *base, uint32_t size)
void *SAPI salloc(void *base, uint32_t size)
{
void* result = NULL;
if(base != NULL && size != 0)
void *result = NULL;
if (base != NULL && size != 0)
{
uint32_t total_size = size + sizeof(alloc_header);
char* c_ptr = (char*)base;
while(1)
uint32_t total_size = size + sizeof(_salloc_header);
char *c_ptr = (char *) base;
while (1)
{
uint32_t cur_blk_free = _read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t cur_blk_size = _read_alloc_header_size((alloc_header *) c_ptr);
uint32_t cur_blk_last = _read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
if(cur_blk_free == 0 || cur_blk_size < total_size)
uint32_t cur_blk_free = _read_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t cur_blk_size = _read_salloc_header_size((_salloc_header *) c_ptr);
uint32_t cur_blk_last = _read_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
if (cur_blk_free == 0 || cur_blk_size < total_size)
{
//if cur block not a free block
//or the current block size is less than the size we want
if(cur_blk_last == 1)
if (cur_blk_last == 1)
//if last one, break and fail.
break;
else
@ -149,28 +150,29 @@ void* salloc(void *base, uint32_t size)
else
{
// we have a free block with enough size
if(total_size == cur_blk_size ||
cur_blk_size - total_size < sizeof(alloc_header))
if (total_size == cur_blk_size ||
cur_blk_size - total_size < sizeof(_salloc_header))
{
// since the space left is not enough for alloc_header
// since the space left is not enough for salloc_header
// we alloc the whole block
_set_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 0);
_set_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 0);
}
else
{
// we split the block here
// set properties for the first block
_set_alloc_header_size((alloc_header *) c_ptr, total_size);
_set_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, 0);
_set_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 0);
_set_salloc_header_size((_salloc_header *) c_ptr, total_size);
_set_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST, 0);
_set_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 0);
// set properties for the second block
_set_alloc_header_size((alloc_header *) (c_ptr + total_size), cur_blk_size - total_size);
_set_alloc_header_flag((alloc_header *) (c_ptr + total_size), ALLOC_HEADER_FLAG_LAST, cur_blk_last);
_set_alloc_header_flag((alloc_header *) (c_ptr + total_size), ALLOC_HEADER_FLAG_FREE, 1);
_set_salloc_header_size((_salloc_header *) (c_ptr + total_size), cur_blk_size - total_size);
_set_salloc_header_flag((_salloc_header *) (c_ptr + total_size), ALLOC_HEADER_FLAG_LAST,
cur_blk_last);
_set_salloc_header_flag((_salloc_header *) (c_ptr + total_size), ALLOC_HEADER_FLAG_FREE, 1);
}
// return the pointer, skip the alloc header
result = c_ptr + sizeof(alloc_header);
result = c_ptr + sizeof(_salloc_header);
break;
}
}
@ -178,26 +180,26 @@ void* salloc(void *base, uint32_t size)
return result;
}
void sfree(void *base, void *ptr)
void SAPI sfree(void *base, void *ptr)
{
if(base != NULL && ptr != NULL)
if (base != NULL && ptr != NULL)
{
char* c_ptr = (char*)base;
while(1)
char *c_ptr = (char *) base;
while (1)
{
uint32_t cur_blk_free = _read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t cur_blk_last = _read_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t cur_blk_size = _read_alloc_header_size((alloc_header *) c_ptr);
if (cur_blk_free == 0 && ptr == c_ptr + sizeof(alloc_header))
uint32_t cur_blk_free = _read_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE);
uint32_t cur_blk_last = _read_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_LAST);
uint32_t cur_blk_size = _read_salloc_header_size((_salloc_header *) c_ptr);
if (cur_blk_free == 0 && ptr == c_ptr + sizeof(_salloc_header))
{
// we found the block, mark it as free
_set_alloc_header_flag((alloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 1);
_set_salloc_header_flag((_salloc_header *) c_ptr, ALLOC_HEADER_FLAG_FREE, 1);
// merge blocks
_alloc_join(base);
_salloc_join(base);
break;
}
if(cur_blk_last == 1)
if (cur_blk_last == 1)
{
break;
}

View File

@ -14,6 +14,7 @@ void SAPI kmain(multiboot_info_t *multiboot_info)
linked_list_test();
avl_tree_test();
salloc_test();
if(boot_info->mem_info != NULL)
{

View File

@ -5,4 +5,6 @@ void SAPI linked_list_test(void);
void SAPI avl_tree_test(void);
void SAPI salloc_test(void);
#endif

View File

@ -0,0 +1,281 @@
#include "k_test_driver.h"
#include "salloc.h"
typedef union
{
uint32_t size;
uint32_t flags;
} _salloc_header;
const uint32_t salloc_header_size = sizeof(_salloc_header);
static char buffer[1024];
static bool salloc_init_test()
{
salloc_init(buffer, 1024);
uint32_t blk_size[] = {1024};
bool blk_free[] = {true};
return salloc_assert(buffer,blk_size, blk_free, 1);
}
static bool salloc_basic_alloc()
{
bool result = true;
salloc_init(buffer, 1024);
result = result && (salloc(buffer, 10) != NULL);
uint32_t blk_size[] = {10 + salloc_header_size, 1024-10-salloc_header_size};
bool blk_free[] = {false,true};
result = result && salloc_assert(buffer,blk_size, blk_free, 2);
return result;
}
static bool salloc_full_alloc()
{
bool result = true;
salloc_init(buffer, 1024);
result = result && (salloc(buffer, 1024 - salloc_header_size) != NULL);
uint32_t blk_size[] = {1024};
bool blk_free[] = {false};
result = result && salloc_assert(buffer,blk_size, blk_free, 1);
return result;
}
static bool salloc_overflow_alloc()
{
bool result = true;
salloc_init(buffer, 1024);
result = result && (salloc(buffer, 1024 - salloc_header_size + 1) == NULL);
uint32_t blk_size[] = {1024};
bool blk_free[] = {true};
result = result && salloc_assert(buffer,blk_size, blk_free, 1);
return result;
}
static bool salloc_multiple_alloc()
{
bool result = true;
salloc_init(buffer, 1024);
result = result && (salloc(buffer, 10) != NULL);
result = result && (salloc(buffer, 10) != NULL);
result = result && (salloc(buffer, 10) != NULL);
uint32_t blk_size[] = {10 + salloc_header_size,
10 + salloc_header_size,
10 + salloc_header_size,
1024-3*(10+salloc_header_size)};
bool blk_free[] = {false,false,false,true};
result = result && salloc_assert(buffer,blk_size, blk_free, 4);
return result;
}
static bool salloc_alloc_not_enough()
{
void* ptr;
bool result = true;
salloc_init(buffer, salloc_header_size + salloc_header_size + salloc_header_size - 1);
ptr = salloc(buffer, salloc_header_size);
result = result && (ptr != NULL);
uint32_t blk_size[] = {salloc_header_size + salloc_header_size + salloc_header_size - 1};
bool blk_free[] = {false};
result = result && salloc_assert(buffer,blk_size, blk_free, 1);
return result;
}
static bool salloc_basic_free()
{
void* ptr;
bool result = true;
salloc_init(buffer, 1024);
ptr = salloc(buffer, 10);
result = result && (ptr != NULL);
sfree(buffer, ptr);
uint32_t blk_size[] = {1024};
bool blk_free[] = {true};
result = result && salloc_assert(buffer,blk_size, blk_free, 1);
return result;
}
static bool salloc_full_free()
{
void* ptr;
bool result = true;
salloc_init(buffer, 1024);
ptr = salloc(buffer, 1024 - salloc_header_size);
result = result && (ptr != NULL);
sfree(buffer, ptr);
uint32_t blk_size[] = {1024};
bool blk_free[] = {true};
result = result && salloc_assert(buffer,blk_size, blk_free, 1);
return result;
}
static bool salloc_multiple_free()
{
void* ptr1, *ptr2, *ptr3, *ptr4;
bool result = true;
salloc_init(buffer, 1024);
ptr1 = salloc(buffer, 10);
ptr2 = salloc(buffer, 10);
ptr3 = salloc(buffer, 10);
ptr4 = salloc(buffer, 10);
result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL);
sfree(buffer, ptr1);
sfree(buffer, ptr3);
uint32_t blk_size[] = {10 + salloc_header_size,
10 + salloc_header_size,
10 + salloc_header_size,
10 + salloc_header_size,
1024-4*(10+salloc_header_size)};
bool blk_free[] = {true,false,true,false,true};
result = result && salloc_assert(buffer,blk_size, blk_free, 5);
return result;
}
static bool salloc_free_join_tail()
{
void* ptr1, *ptr2, *ptr3, *ptr4;
bool result = true;
salloc_init(buffer, 1024);
ptr1 = salloc(buffer, 10);
ptr2 = salloc(buffer, 10);
ptr3 = salloc(buffer, 10);
ptr4 = salloc(buffer, 10);
result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL);
sfree(buffer, ptr4);
uint32_t blk_size[] = {10 + salloc_header_size,
10 + salloc_header_size,
10 + salloc_header_size,
1024-3*(10+salloc_header_size)};
bool blk_free[] = {false,false,false,true};
result = result && salloc_assert(buffer,blk_size, blk_free, 4);
return result;
}
static bool salloc_free_join_head()
{
void* ptr1, *ptr2, *ptr3, *ptr4;
bool result = true;
salloc_init(buffer, 1024);
ptr1 = salloc(buffer, 10);
ptr2 = salloc(buffer, 10);
ptr3 = salloc(buffer, 10);
ptr4 = salloc(buffer, 10);
result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL);
sfree(buffer, ptr1);
sfree(buffer, ptr2);
uint32_t blk_size[] = {2*(10 + salloc_header_size),
10 + salloc_header_size,
10 + salloc_header_size,
1024-4*(10+salloc_header_size)};
bool blk_free[] = {true,false,false,true};
result = result && salloc_assert(buffer,blk_size, blk_free, 4);
return result;
}
static bool salloc_free_join_mid()
{
void* ptr1, *ptr2, *ptr3, *ptr4;
bool result = true;
salloc_init(buffer, 1024);
ptr1 = salloc(buffer, 10);
ptr2 = salloc(buffer, 10);
ptr3 = salloc(buffer, 10);
ptr4 = salloc(buffer, 10);
result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL);
sfree(buffer, ptr2);
sfree(buffer, ptr3);
uint32_t blk_size[] = {10 + salloc_header_size,
2*(10 + salloc_header_size),
10 + salloc_header_size,
1024-4*(10+salloc_header_size)};
bool blk_free[] = {false,true,false,true};
result = result && salloc_assert(buffer,blk_size, blk_free, 4);
return result;
}
static bool salloc_free_join_consecutive()
{
void* ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
bool result = true;
salloc_init(buffer, 1024);
ptr1 = salloc(buffer, 10);
ptr2 = salloc(buffer, 10);
ptr3 = salloc(buffer, 10);
ptr4 = salloc(buffer, 10);
ptr5 = salloc(buffer, 10);
result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL) && (ptr5 != NULL);
sfree(buffer, ptr2);
sfree(buffer, ptr4);
uint32_t blk_size[] = {10 + salloc_header_size,
10 + salloc_header_size,
10 + salloc_header_size,
10 + salloc_header_size,
10 + salloc_header_size,
1024-5*(10+salloc_header_size)};
bool blk_free[] = {false,true,false,true,false,true};
result = result && salloc_assert(buffer,blk_size, blk_free, 6);
sfree(buffer, ptr3);
uint32_t blk_size2[] = {10 + salloc_header_size,
3*(10 + salloc_header_size),
10 + salloc_header_size,
1024-5*(10+salloc_header_size)};
bool blk_free2[] = {false,true,false,true};
result = result && salloc_assert(buffer,blk_size2, blk_free2, 4);
return result;
}
static bool salloc_free_all()
{
void* ptr1, *ptr2, *ptr3, *ptr4;
bool result = true;
salloc_init(buffer, 1024);
ptr1 = salloc(buffer, 10);
ptr2 = salloc(buffer, 10);
ptr3 = salloc(buffer, 10);
ptr4 = salloc(buffer, 10);
result = result && (ptr1 != NULL) && (ptr2 != NULL) && (ptr3 != NULL) && (ptr4 != NULL);
sfree(buffer, ptr1);
sfree(buffer, ptr2);
sfree(buffer, ptr3);
sfree(buffer, ptr4);
uint32_t blk_size[] = {1024};
bool blk_free[] = {true};
result = result && salloc_assert(buffer,blk_size, blk_free, 1);
return result;
}
void SAPI salloc_test()
{
test_begin("salloc test");
run_case("salloc_init_test", salloc_init_test());
run_case("salloc_basic_alloc", salloc_basic_alloc());
run_case("salloc_full_alloc", salloc_full_alloc());
run_case("salloc_overflow_alloc", salloc_overflow_alloc());
run_case("salloc_multiple_alloc", salloc_multiple_alloc());
run_case("salloc_alloc_not_enough", salloc_alloc_not_enough());
run_case("salloc_basic_free", salloc_basic_free());
run_case("salloc_full_free", salloc_full_free());
run_case("salloc_multiple_free", salloc_multiple_free());
run_case("salloc_free_join_tail", salloc_free_join_tail());
run_case("salloc_free_join_head", salloc_free_join_head());
run_case("salloc_free_join_mid", salloc_free_join_mid());
run_case("salloc_free_join_consecutive", salloc_free_join_consecutive());
run_case("salloc_free_all", salloc_free_all());
test_end();
}