[lib][heap] fix some formatting and a bug or two in the novm and page alloc stuff

This commit is contained in:
Travis Geiselbrecht
2015-10-15 15:46:35 -07:00
parent 3bbc7ac101
commit 80bf0a48b4
3 changed files with 126 additions and 125 deletions

View File

@@ -55,21 +55,21 @@ extern int _end_of_ram;
#endif
char allocation_map[DEFAULT_MAP_SIZE];
static char allocation_map[DEFAULT_MAP_SIZE];
struct novm {
mutex_t lock;
mutex_t lock;
size_t pages;
char* map;
char* map;
char* heap_base;
uintptr_t heap_size;
};
static bool in_heap(struct novm *n, void* p)
{
char *ptr = (char *)p;
char *base = n->heap_base;
return ptr >= base && ptr < base + n->heap_size;
char *ptr = (char *)p;
char *base = n->heap_base;
return ptr >= base && ptr < base + n->heap_size;
}
struct novm sram_heap;
@@ -82,42 +82,43 @@ struct novm sdram_heap;
static void* unaligned_area = NULL;
static size_t unaligned_size = 0;
void *novm_alloc_unaligned(size_t *size_return) {
if (unaligned_area != NULL) {
*size_return = unaligned_size;
void *result = unaligned_area;
unaligned_area = NULL;
return result;
}
*size_return = PAGE_SIZE;
return novm_alloc_pages(1);
void *novm_alloc_unaligned(size_t *size_return)
{
if (unaligned_area != NULL) {
*size_return = unaligned_size;
void *result = unaligned_area;
unaligned_area = NULL;
return result;
}
*size_return = PAGE_SIZE;
return novm_alloc_pages(1);
}
void novm_init_helper(
struct novm* n, uintptr_t heap_start,
uintptr_t heap_size, char* default_map, size_t default_map_size)
uintptr_t heap_size, char* default_map, size_t default_map_size)
{
uintptr_t start = ROUNDUP(heap_start, PAGE_SIZE);
uintptr_t size = ROUNDDOWN(heap_start + heap_size, PAGE_SIZE) - start;
mutex_init(&n->lock);
uintptr_t start = ROUNDUP(heap_start, PAGE_SIZE);
uintptr_t size = ROUNDDOWN(heap_start + heap_size, PAGE_SIZE) - start;
mutex_init(&n->lock);
size_t map_size = size >> PAGE_SIZE_SHIFT;
char* map = default_map;
if (map == NULL || default_map_size < map_size) {
map = (char *)heap_start;
// Grab enough map for 16Mbyte of heap each time around the loop.
while (start - heap_start < map_size) {
start += PAGE_SIZE;
size -= PAGE_SIZE;
map_size--;
}
if ((char *)start - (map + map_size) >= MINIMUM_USEFUL_UNALIGNED_SIZE) {
unaligned_area = map + map_size;
unaligned_size = (char *)start - (map + map_size);
}
map = (char *)heap_start;
// Grab enough map for 16Mbyte of heap each time around the loop.
while (start - heap_start < map_size) {
start += PAGE_SIZE;
size -= PAGE_SIZE;
map_size--;
}
if ((char *)start - (map + map_size) >= MINIMUM_USEFUL_UNALIGNED_SIZE) {
unaligned_area = map + map_size;
unaligned_size = (char *)start - (map + map_size);
}
} else if (start - heap_start >= MINIMUM_USEFUL_UNALIGNED_SIZE) {
unaligned_area = (char *)heap_start;
unaligned_size = start - heap_start;
}
unaligned_area = (char *)heap_start;
unaligned_size = start - heap_start;
}
n->map = map;
memset(n->map, 0, map_size);
n->pages = map_size;
@@ -125,44 +126,45 @@ void novm_init_helper(
n->heap_size = size;
}
void novm_init(void) {
novm_init_helper(&sram_heap, HEAP_START, HEAP_LEN, allocation_map, DEFAULT_MAP_SIZE);
void novm_init(void)
{
novm_init_helper(&sram_heap, HEAP_START, HEAP_LEN, allocation_map, DEFAULT_MAP_SIZE);
#ifdef SDRAM_BASE
#define SDRAM_MAP_SIZE (SDRAM_SIZE >> PAGE_SIZE_SHIFT)
static char sdram_map[SDRAM_MAP_SIZE];
novm_init_helper(&sdram_heap, SDRAM_BASE, SDRAM_BASE + SDRAM_SIZE, sdram_map, SDRAM_MAP_SIZE);
static char sdram_map[SDRAM_MAP_SIZE];
novm_init_helper(&sdram_heap, SDRAM_BASE, SDRAM_SIZE, sdram_map, SDRAM_MAP_SIZE);
#endif
}
void *novm_alloc_helper(struct novm *n, size_t pages)
{
mutex_acquire(&n->lock);
for (size_t i = 0; i <= n->pages - pages; i++) {
bool found = true;
for (size_t j = 0; j < pages; j++) {
if (n->map[i + j] != 0) {
i += j;
found = false;
break;
}
}
if (found) {
memset(n->map + i, 1, pages);
mutex_release(&n->lock);
return n->heap_base + (i << PAGE_SIZE_SHIFT);
}
}
mutex_release(&n->lock);
return NULL;
mutex_acquire(&n->lock);
for (size_t i = 0; i <= n->pages - pages; i++) {
bool found = true;
for (size_t j = 0; j < pages; j++) {
if (n->map[i + j] != 0) {
i += j;
found = false;
break;
}
}
if (found) {
memset(n->map + i, 1, pages);
mutex_release(&n->lock);
return n->heap_base + (i << PAGE_SIZE_SHIFT);
}
}
mutex_release(&n->lock);
return NULL;
}
void* novm_alloc_pages(size_t pages)
{
void* result = novm_alloc_helper(&sram_heap, pages);
void* result = novm_alloc_helper(&sram_heap, pages);
if (result != NULL) return result;
#ifdef SDRAM_BASE
return novm_alloc_helper(&sdram_heap, pages);
return novm_alloc_helper(&sdram_heap, pages);
#endif
return NULL;
}
@@ -176,14 +178,14 @@ void novm_free_pages(void* address, size_t pages)
struct novm *n = &sram_heap;
#endif
DEBUG_ASSERT(in_heap(n, address));
DEBUG_ASSERT(in_heap(n, address));
size_t index = ((char *)address - (char*)(n->heap_base)) >> PAGE_SIZE_SHIFT;
size_t index = ((char *)address - (char*)(n->heap_base)) >> PAGE_SIZE_SHIFT;
char *map = n->map;
mutex_acquire(&n->lock);
for (size_t i = 0; i < pages; i++) map[index + i] = 0;
mutex_release(&n->lock);
mutex_acquire(&n->lock);
for (size_t i = 0; i < pages; i++) map[index + i] = 0;
mutex_release(&n->lock);
}
#if LK_DEBUGLEVEL > 1
@@ -200,48 +202,49 @@ STATIC_COMMAND_END(novm);
static int cmd_novm(int argc, const cmd_args *argv)
{
if (argc != 2) {
if (argc != 2) {
notenoughargs:
printf("not enough arguments\n");
printf("not enough arguments\n");
usage:
printf("usage:\n");
printf("\t%s info\n", argv[0].str);
return -1;
}
printf("usage:\n");
printf("\t%s info\n", argv[0].str);
return -1;
}
if (strcmp(argv[1].str, "info") == 0) {
novm_dump();
} else {
printf("unrecognized command\n");
goto usage;
}
if (strcmp(argv[1].str, "info") == 0) {
novm_dump();
} else {
printf("unrecognized command\n");
goto usage;
}
return 0;
return 0;
}
static void novm_dump_area(struct novm *n) {
mutex_acquire(&n->lock);
printf(" %d pages, each %zdk (%zdk in all)\n", n->pages, PAGE_SIZE >> 10, (PAGE_SIZE * n->pages) >> 10);
printf(" %p-%p\n", (void *)n->heap_base, (char *)n->heap_base + n->heap_size);
static void novm_dump_area(struct novm *n)
{
mutex_acquire(&n->lock);
printf(" %d pages, each %zdk (%zdk in all)\n", n->pages, PAGE_SIZE >> 10, (PAGE_SIZE * n->pages) >> 10);
printf(" %p-%p\n", (void *)n->heap_base, (char *)n->heap_base + n->heap_size);
#define MAX_PRINT 1024u
unsigned i;
for (i = 0; i < MAX_PRINT && i < n->pages; i++) {
if ((i & 63) == 0) printf(" ");
printf("%c", n->map[i] ? '*' : '.');
if ((i & 63) == 63) printf("\n");
}
if (i == MAX_PRINT && n->pages > MAX_PRINT) printf(" ...");
printf("\n");
mutex_release(&n->lock);
unsigned i;
for (i = 0; i < MAX_PRINT && i < n->pages; i++) {
if ((i & 63) == 0) printf(" ");
printf("%c", n->map[i] ? '*' : '.');
if ((i & 63) == 63) printf("\n");
}
if (i == MAX_PRINT && n->pages > MAX_PRINT) printf(" ...");
printf("\n");
mutex_release(&n->lock);
}
static void novm_dump(void)
{
printf("SRAM area:\n");
novm_dump_area(&sram_heap);
printf("SRAM area:\n");
novm_dump_area(&sram_heap);
#ifdef SDRAM_BASE
printf("SDRAM area:\n");
novm_dump_area(&sdram_heap);
printf("SDRAM area:\n");
novm_dump_area(&sdram_heap);
#endif
}