diff --git a/Makefile b/Makefile index ba9a109..807e47e 100644 --- a/Makefile +++ b/Makefile @@ -75,13 +75,10 @@ $(BUILD_DIR)/compile_commands.json: @./tools/make/generate_compile_commands.py -sandbox: - @$(MAKE) -C sandbox - compile-db: $(BUILD_DIR)/compile_commands.json include arch/$(ARCH)/extra.mk -.PHONY: all compile-db sandbox +.PHONY: all compile-db .INTERMEDIATE: $(ARCH_TEMP_FILES) diff --git a/sandbox/Makefile b/sandbox/Makefile deleted file mode 100644 index 71f1d85..0000000 --- a/sandbox/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -THIS_FILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) -SANDBOX_PROG_MAKEFILE_PATH := $(abspath $(firstword $(MAKEFILE_LIST))) -SANDBOX_BASE_DIR := $(patsubst %/,%,$(dir $(THIS_FILE_PATH))) -SANDBOX_PROG_DIR := $(patsubst %/,%,$(dir $(SANDBOX_PROG_MAKEFILE_PATH))) -BUILD_DIR := $(SANDBOX_BASE_DIR)/../build/sandbox - -include $(SANDBOX_BASE_DIR)/../tools/make/gcc-host.mk -EXEC_NAME := sandbox -DIR_LIST := memblock vm base queue btree util locks -INCLUDE_DIRS := $(foreach dir,$(DIR_LIST),-I$(dir)/include) -SRC := $(foreach dir,$(DIR_LIST),$(wildcard $(dir)/*.c)) -OBJ := $(addprefix $(BUILD_DIR)/,$(SRC:.c=.o)) -DEPS := $(OBJ:.o=.d) - -CFLAGS := $(INCLUDE_DIRS) -g -LDFLAGS := -pthread - -all: $(BUILD_DIR)/$(EXEC_NAME) - @for prog in $(SANDBOX_DIR_LIST); do \ - $(MAKE) -C $$prog; \ - done - -$(BUILD_DIR)/$(EXEC_NAME): $(OBJ) - @mkdir -p $(@D) - - @printf " \033[1;36mHOSTLD\033[0m \033[1mbuild/sandbox/\033[35m$(EXEC_NAME)\n" - @$(CC) $(OBJ) -o $@ $(CFLAGS) $(LDFLAGS) - --include $(DEPS) - -$(BUILD_DIR)/%.o: %.c - @printf " \033[1;32mHOSTCC\033[0m \033[35msandbox\033[0m/$<\n" - @mkdir -p $(@D) - - @$(CC) $< -o $@ -c $(CFLAGS) -MMD - -.PHONY: all diff --git a/sandbox/base/btree_test.c b/sandbox/base/btree_test.c deleted file mode 100644 index dfd0363..0000000 --- a/sandbox/base/btree_test.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NR_BTREE_NODES 32 - -struct tree_node { - btree_node_t base; - unsigned int key; -}; - -static int btree_comparator(struct tree_node *a, struct tree_node *b) -{ - if (a->key > b->key) { - return 1; - } else if (a->key < b->key) { - return -1; - } else { - return 0; - } -} - - -//BTREE_DEFINE_SIMPLE_INSERT(struct tree_node, base, key, insert) -BTREE_DEFINE_INSERT(struct tree_node, base, key, insert, btree_comparator); -BTREE_DEFINE_SIMPLE_GET(struct tree_node, unsigned int, base, key, get); - -void tree_print(struct tree_node *node, int depth) -{ - if (!node) { - return; - } - - tree_print(BTREE_CONTAINER(struct tree_node, base, btree_right(&node->base)), depth + 1); - - for (int i = 0; i < depth; i++) { - fputs(" ", stdout); - } - - printf("%u (h:%d)\n", node->key, btree_height(&node->base)); - - tree_print(BTREE_CONTAINER(struct tree_node, base, btree_left(&node->base)), depth + 1); -} - -/* returns the height of the subtree rooted at node x, or -1 if one of these conditions is true: - * - the calculated height of subtree x does not match the stored height value. - * - the subtree is not a valid AVL tree. - */ -static int btree_avl_validate(btree_node_t *x) -{ - if (!x) { - return 0; - } - - if (!x->b_left && !x->b_right) { - return x->b_height == 1 ? 1 : -1; - } - - int left = 0, right = 0; - - if (x->b_left) { - left = btree_avl_validate(x->b_left); - } - - if (x->b_right) { - right = btree_avl_validate(x->b_right); - } - - if (left == -1 || right == -1) { - return -1; - } - - int diff = right - left; - if (diff > 1 || diff < -1) { - return -1; - } - - int height = 0; - - if (left > right) { - height = left + 1; - } else { - height = right + 1; - } - - if (height != x->b_height) { - return -1; - } - - return height; -} - -static unsigned int alloc_unique_key(struct tree_node *nodes, size_t count) -{ - while (1) { - unsigned int k = (rand() % 8192) + 1; - - for (size_t i = 0; i < count; i++) { - if (nodes[i].key == k) { - continue; - } - } - - return k; - } - - return (unsigned int)-1; -} - -int btree_test(void) -{ - btree_t tree = {}; - struct tree_node *nodes = calloc(NR_BTREE_NODES, sizeof *nodes); - - for (int i = 0; i < NR_BTREE_NODES; i++) { - nodes[i].key = alloc_unique_key(nodes, i); - printf(" - node %d: %u\n", i, nodes[i].key); - } - - int validation_result = 0; - for (int i = 0; i < NR_BTREE_NODES; i++) { - printf("#######################\n"); - printf("inserting node #%d: %u\n", i, nodes[i].key); - - insert(&tree, &nodes[i]); - tree_print(BTREE_CONTAINER(struct tree_node, base, tree.b_root), 0); - printf("#######################\n"); - - validation_result = btree_avl_validate(tree.b_root); - - for (int ii = 0; ii < NR_BTREE_NODES; ii++) { - struct tree_node *n = get(&tree, nodes[ii].key); - - if (ii <= i) { - assert(n && n->key == nodes[ii].key); - } else { - assert(!n); - } - } - - assert(validation_result >= 1); - } - - tree_print(BTREE_CONTAINER(struct tree_node, base, tree.b_root), 0); - - int result = btree_avl_validate(tree.b_root); - printf("AVL tree height: %d\n", result); - - printf("in-order traversal:\n"); - btree_foreach (struct tree_node, node, &tree, base) { - printf(" - %u\n", node->key); - } - - printf("reverse-order traversal:\n"); - btree_foreach_r (struct tree_node, node, &tree, base) { - printf(" - %u\n", node->key); - } - - for (int i = 0; i < NR_BTREE_NODES; i++) { - printf("#######################\n"); - printf("deleting node #%d: %u\n", i, nodes[i].key); - printf("#######################\n"); - - btree_delete(&tree, &nodes[i].base); - tree_print(BTREE_CONTAINER(struct tree_node, base, tree.b_root), 0); - - for (int ii = 0; ii < NR_BTREE_NODES; ii++) { - struct tree_node *n = get(&tree, nodes[ii].key); - - if (ii <= i) { - assert(!n); - } else { - assert(n && n->key == nodes[ii].key); - } - } - - validation_result = btree_avl_validate(tree.b_root); - assert(validation_result >= 0); - } - - free(nodes); - return 0; -} diff --git a/sandbox/base/main.c b/sandbox/base/main.c deleted file mode 100644 index 63d0d80..0000000 --- a/sandbox/base/main.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int memory_test(void); -extern int btree_test(void); -extern int queue_test(void); - -int main(int argc, const char **argv) -{ - memory_test(); - return 0; -} diff --git a/sandbox/base/memory_test.c b/sandbox/base/memory_test.c deleted file mode 100644 index 619f30d..0000000 --- a/sandbox/base/memory_test.c +++ /dev/null @@ -1,299 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NR_THREADS 8 - -/* we're working with 512MiB of simulated system RAM */ -#define MEMORY_SIZE_MB 512 - -#define ALLOC_START_MB 16 -#define ALLOC_END_MB 32 - -#define MEMPTR(offset) ((uintptr_t)system_memory + (offset)) -#define MB_TO_BYTES(v) ((size_t)(v) * 0x100000) - -#define PHYS_TO_VIRT(p) ((void *)((uintptr_t)system_memory + (p))) -#define VIRT_TO_PHYS(p) ((void *)((p) - (uintptr_t)system_memory)) - -struct mem_map_region { - phys_addr_t base; - phys_addr_t limit; - enum { REGION_FREE, REGION_RESERVED } status; -}; - -static struct mem_map_region mem_map[] = { - { .base = 0x00000000, .limit = 0x0000ffff, .status = REGION_RESERVED }, - { .base = 0x00010000, .limit = 0x0004ffff, .status = REGION_FREE }, - { .base = 0x00050000, .limit = 0x0005ffff, .status = REGION_RESERVED }, - { .base = 0x00060000, .limit = 0x000fffff, .status = REGION_FREE }, - { .base = 0x00100000, .limit = 0x001fffff, .status = REGION_RESERVED }, - { .base = 0x00200000, .limit = 0x005fffff, .status = REGION_FREE }, - { .base = 0x00600000, .limit = 0x007fffff, .status = REGION_RESERVED }, - { .base = 0x00800000, .limit = MB_TO_BYTES(MEMORY_SIZE_MB) - 1, .status = REGION_FREE }, -}; - -extern void tmp_set_vaddr_base(void *, size_t); - -/* virtual address of where system memory is mapped */ -static void *system_memory = NULL; - -static void print_free_pages(vm_zone_t *z) -{ - printf(" * %s:\n", z->z_info.zd_name); - - for (int i = VM_PAGE_MIN_ORDER; i <= VM_PAGE_MAX_ORDER; i++) { - if (queue_empty(&z->z_free_pages[i])) { - continue; - } - - char size_str[64]; - data_size_to_string(vm_page_order_to_bytes(i), size_str, sizeof size_str); - - printf(" - %zu pages with size %s (order-%u)\n", queue_length(&z->z_free_pages[i]), size_str, i); - } -} - -static void *kmalloc_test_thread(void *p) -{ - size_t thread_id = (size_t)p; - struct timespec ts = { .tv_sec = 1 }; - void *allocated[4096]; - while (1) { - int op = rand() % 2; - if (op == 1) { - for (int i = 0; i < 4096; i++) { - if (!allocated[i]) { - unsigned int size = (rand() % 4095) + 1; - allocated[i] = kmalloc(size, 0); - printf("thread %zu: allocated %u bytes at %p\n", thread_id, size, allocated[i]); - assert(allocated[i]); - break; - } - } - } else { - for (int i = 4095; i >= 0; i--) { - if (allocated[i]) { - kfree(allocated[i]); - printf("thread %zu: freed %p\n", thread_id, allocated[i]); - allocated[i] = NULL; - break; - } - } - } - - //nanosleep(&ts, NULL); - } - - return NULL; -} - -static void print_all_pages(void) -{ - for (phys_addr_t i = 0; i < UINTPTR_MAX; ) { - vm_page_t *pg = vm_page_get(i); - if (!pg) { - break; - } - - vm_zone_t *z = vm_page_get_zone(pg); - printf(" * %08" PRIxPTR ": %s order-%u (%zu bytes) %s\n", - i, - z ? z->z_info.zd_name : "[none]", - pg->p_order, - vm_page_order_to_bytes(pg->p_order), - pg->p_flags & VM_PAGE_RESERVED ? "reserved" : "free"); - i += vm_page_order_to_bytes(pg->p_order); - } -} - -int memory_test(void) -{ - srand(time(NULL)); - system_memory = mmap( - NULL, - MB_TO_BYTES(MEMORY_SIZE_MB), - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); - - if (system_memory == MAP_FAILED) { - perror("mmap"); - fprintf(stderr, "cannot allocate simulated system RAM buffer\n"); - return -1; - } - - phys_addr_t pmem_base = UINTPTR_MAX, pmem_limit = 0; - size_t nr_mem_map_entries = sizeof mem_map / sizeof mem_map[0]; - - for (size_t i = 0; i < nr_mem_map_entries; i++) { - if (mem_map[i].base < pmem_base) { - pmem_base = mem_map[i].base; - } - - if (mem_map[i].limit > pmem_limit) { - pmem_limit = mem_map[i].limit; - } - } - - printf("virtual memory range: 0x%" PRIxPTR "-0x%" PRIxPTR "\n", (uintptr_t)system_memory, (uintptr_t)system_memory + MB_TO_BYTES(MEMORY_SIZE_MB)); - - tmp_set_vaddr_base(system_memory, MB_TO_BYTES(MEMORY_SIZE_MB)); - memblock_add(pmem_base, pmem_limit + 1); - - for (size_t i = 0; i < nr_mem_map_entries; i++) { - if (mem_map[i].status == REGION_RESERVED) { - memblock_reserve(mem_map[i].base, mem_map[i].limit - mem_map[i].base + 1); - } - } - - printf("allocated %u MiB (0x%zx bytes) of memory to act as system RAM at %p\n", MEMORY_SIZE_MB, MB_TO_BYTES(MEMORY_SIZE_MB), system_memory); - - printf("sizeof(vm_page_t) = %zu bytes\n", sizeof(vm_page_t)); - - uintptr_t voffset = (uintptr_t)system_memory; - - memblock_init(MB_TO_BYTES(ALLOC_START_MB) + voffset, MB_TO_BYTES(ALLOC_END_MB) + voffset, voffset); - - printf("memblock heap initialised in 0x%zx-0x%zx\n", MB_TO_BYTES(ALLOC_START_MB), MB_TO_BYTES(ALLOC_END_MB)); - - for (int i = 0; i < 4; i++) { - int size = 512 + (rand() % 16384); - - phys_addr_t alloc = memblock_alloc_phys(size); - printf("allocated %d bytes at 0x%" PRIxPTR "\n", size, alloc); - } - - vm_zone_descriptor_t zones[] = { - { .zd_id = VM_ZONE_DMA, .zd_name = "dma", .zd_base = 0x0, .zd_limit = MB_TO_BYTES(16) - 1 }, - { .zd_id = VM_ZONE_NORMAL, .zd_name = "normal", .zd_base = MB_TO_BYTES(16), .zd_limit = MB_TO_BYTES(1024) - 1 }, - { .zd_id = VM_ZONE_HIGHMEM, .zd_name = "highmem", .zd_base = MB_TO_BYTES(1024), .zd_limit = UINTPTR_MAX }, - }; - - vm_bootstrap(zones, sizeof zones / sizeof zones[0]); - - printf("memory regions:\n"); - - memblock_iter_t it; - for_each_mem_range(&it, 0, 0x100000) { - printf("\t%08" PRIxPTR "-%08" PRIxPTR "\n", - it.it_base, - it.it_limit); - } - - printf("reserved regions:\n"); - for_each_reserved_mem_range(&it, 0, 0x100000) { - printf("\t%08" PRIxPTR "-%08" PRIxPTR " (%s)\n", - it.it_base, - it.it_limit, - it.it_status == MEMBLOCK_ALLOC ? "allocated" : "reserved"); - } - - printf("free regions:\n"); - for_each_free_mem_range(&it, 0, ULLONG_MAX) { - printf("\t%08" PRIxPTR "-%08" PRIxPTR "\n", - it.it_base, - it.it_limit); - } - - vm_pg_data_t *pg_data = vm_pg_data_get(0); - printf("free pages:\n"); - for (int i = VM_ZONE_MIN; i <= VM_ZONE_MAX; i++) { - print_free_pages(&pg_data->pg_zones[i]); - } - - vm_page_t *pg = vm_page_alloc(VM_PAGE_128K, 0); - printf("allocated 128K at 0x%lx\n", vm_page_get_paddr(pg)); - - vm_page_t *a, *b; - if (vm_page_split(pg, &a, &b) == 0) { - printf("split page into two 64K pages at 0x%lx and 0x%lx:\n", vm_page_get_paddr(a), vm_page_get_paddr(b)); - - assert(a->p_flags & VM_PAGE_HEAD); - assert(b->p_flags & VM_PAGE_HEAD); - - printf("first page block:\n"); - vm_page_foreach (a, i) { - printf(" 0x%lx: order:%u, flags:0x%x\n", vm_page_get_paddr(i), i->p_order, i->p_flags); - assert(i->p_flags & VM_PAGE_HUGE); - assert((i->p_flags & VM_PAGE_RESERVED) == 0); - } - printf("second page block:\n"); - vm_page_foreach (b, i) { - printf(" 0x%lx: order:%u, flags:0x%x\n", vm_page_get_paddr(i), i->p_order, i->p_flags); - assert(i->p_flags & VM_PAGE_HUGE); - assert((i->p_flags & VM_PAGE_RESERVED) == 0); - } - - pg = vm_page_merge(a, b); - if (pg) { - char size_str[64]; - data_size_to_string(vm_page_order_to_bytes(pg->p_order), size_str, sizeof size_str); - printf("merged pages 0x%lx and 0x%lx to single page of size %s:\n", vm_page_get_paddr(a), vm_page_get_paddr(b), size_str); - - size_t block_sz = 0; - vm_page_foreach (pg, i) { - printf(" 0x%lx: order:%u, flags:0x%x\n", vm_page_get_paddr(i), i->p_order, i->p_flags); - assert(i->p_flags & VM_PAGE_HUGE); - assert((i->p_flags & VM_PAGE_RESERVED) == 0); - block_sz += VM_PAGE_SIZE; - } - - assert(block_sz == vm_page_order_to_bytes(pg->p_order)); - - vm_page_free(pg); - } else { - printf("cannot merge pages 0x%lx and 0x%lx\n", vm_page_get_paddr(a), vm_page_get_paddr(b)); - } - } - - pg = vm_page_alloc(VM_PAGE_128K, 0); - printf("allocated 128K at 0x%lx\n", vm_page_get_paddr(pg)); - - if (vm_page_split(pg, &a, &b) == 0) { - assert(a->p_order == VM_PAGE_64K); - assert(b->p_order == VM_PAGE_64K); - - printf("split 128K block into two 64K blocks\n"); - vm_page_free(a); - vm_page_free(b); - - /* if these conditions are true, the two blocks were successfully - merged after being freed. */ - if (a->p_order == VM_PAGE_128K && b->p_order == VM_PAGE_128K) { - printf("two 64K blocks were merged into one 128K block after free\n"); - } else { - printf("two 64K blocks were NOT merged into one 128K block after free!\n"); - } - } - - void *p = kmalloc(32, 0); - printf("kmalloc'd 32 bytes at %p\n", p); - kfree(p); - printf("kfree'd 32 bytes at %p\n", p); - p = kmalloc(32, 0); - printf("kmalloc'd 32 bytes at %p\n", p); - - pthread_t threads[NR_THREADS]; - for (size_t i = 0; i < NR_THREADS; i++) { - pthread_create(&threads[i], NULL, kmalloc_test_thread, (void *)i); - } - - for (size_t i = 0; i < NR_THREADS; i++) { - pthread_join(threads[i], NULL); - } - - munmap(system_memory, MB_TO_BYTES(MEMORY_SIZE_MB)); - return 0; -} diff --git a/sandbox/base/queue_test.c b/sandbox/base/queue_test.c deleted file mode 100644 index 6543be5..0000000 --- a/sandbox/base/queue_test.c +++ /dev/null @@ -1,89 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NR_QUEUE_ITEMS 32 - -struct q_item { - queue_entry_t base; - unsigned int key; -}; - -static struct q_item *find(queue_t *q, unsigned int key) -{ - queue_foreach (struct q_item, item, q, base) { - if (item->key == key) { - return item; - } - } - - return NULL; -} - -int queue_test(void) -{ - queue_t q = {}; - struct q_item *items = calloc(NR_QUEUE_ITEMS, sizeof *items); - - for (int i = 0; i < NR_QUEUE_ITEMS; i++) { - items[i].key = i; - printf(" - item %d: %u\n", i, items[i].key); - } - - for (int i = 0; i < NR_QUEUE_ITEMS; i++) { - printf("#######################\n"); - printf("inserting items #%d: %u\n", i, items[i].key); - - queue_push_back(&q, &items[i].base); - printf("#######################\n"); - - for (int ii = 0; ii < NR_QUEUE_ITEMS; ii++) { - struct q_item *n = find(&q, items[ii].key); - - if (ii <= i) { - assert(n && n->key == items[ii].key); - } else { - assert(!n); - } - } - } - - printf("in-order traversal:\n"); - queue_foreach (struct q_item, item, &q, base) { - printf(" - %u\n", item->key); - } - - printf("reverse-order traversal:\n"); - queue_foreach_r (struct q_item, item, &q, base) { - printf(" - %u\n", item->key); - } - - for (int i = 0; i < NR_QUEUE_ITEMS; i++) { - printf("#######################\n"); - printf("deleting node #%d: %u\n", i, items[i].key); - printf("#######################\n"); - - queue_delete(&q, &items[i].base); - - for (int ii = 0; ii < NR_QUEUE_ITEMS; ii++) { - struct q_item *n = find(&q, items[ii].key); - - if (ii <= i) { - assert(!n); - } else { - assert(n && n->key == items[ii].key); - } - } - } - - free(items); - return 0; -} diff --git a/sandbox/vm/Makefile b/sandbox/vm/Makefile deleted file mode 100644 index 1c7d103..0000000 --- a/sandbox/vm/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -include ../sandbox-config.mk -include ../sandbox-template.mk