#include #include #include #include #include #include #include #include "alloc_api.h" void *main_get_new_region(uintptr_t size) { void *m = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (m == MAP_FAILED) { return NULL; } return m; } void error(char *msg) { printf("=== ALLOCATOR ERROR ===\n%s\n====== END ERROR ======\n", msg); } struct AllocationRecord { uintptr_t size; void *allocation; void *reference; int id; struct AllocationRecord *next; struct AllocationRecord *prev; }; void insert_record(struct AllocationRecord *dummy, void *allocation, uintptr_t size) { struct AllocationRecord *record = malloc(sizeof(struct AllocationRecord)); record->size = size; record->allocation = allocation; record->reference = malloc(size); record->next = dummy; record->prev = dummy->prev; record->id = dummy->id; dummy->prev->next = record; dummy->prev = record; dummy->size += 1; dummy->id += 1; memcpy(record->reference, allocation, size); } void delete_record(struct AllocationRecord *dummy, struct AllocationRecord *delete) { free(delete->reference); delete->prev->next = delete->next; delete->next->prev = delete->prev; free(delete); dummy->size -= 1; } struct AllocationRecord *get_record(struct AllocationRecord *dummy, int which) { struct AllocationRecord *head = dummy->next; while (which--) { head = head->next; } return head; } int validate_record(struct AllocationRecord *record) { if (memcmp(record->allocation, record->reference, record->size) != 0) { return 0; } return 1; } void new_region(struct AllocationRecord *dummy, struct Arena *arena) { uintptr_t size = 1 + (rand() % 8192); uintptr_t align = 1 << (rand() % 4); printf("alloc'ing a region of size %lu with alignment %lu, id %i\n", size, align, dummy->id); void *region = alloc(arena, size, align); if (region == NULL) { printf("memory allocator broke, we have 1L though\n"); return; } for (int ii = 0; ii < size; ii++) { ((char*) region)[ii] = (char) rand(); } insert_record(dummy, region, size); } void delete_region(struct AllocationRecord *dummy, struct Arena *arena) { if (dummy->size == 0) { return; } uintptr_t which = rand() % dummy->size; struct AllocationRecord *zap = get_record(dummy, which); printf("dealloc'ing a region of size %lu, id %i\n", zap->size, zap->id); unalloc(arena, zap->allocation); delete_record(dummy, zap); } int act(struct AllocationRecord *dummy, struct Arena *arena) { if (rand() & 1) { new_region(dummy, arena); } else { delete_region(dummy, arena); } int die = 0; struct AllocationRecord *head = dummy->next; while (head != dummy) { if (!validate_record(head)) { //printf("validation failed at id %i\n", head->id); die = 1; } head = head->next; } return die; } int main() { srand(1); struct Arena arena = { NULL, NULL, main_get_new_region, error, }; void *reg = alloc(&arena, 20, 4); unalloc(&arena, reg); struct AllocationRecord dummy = { .size = 0, .allocation = NULL, .reference = NULL, .id = 0, }; dummy.next = &dummy; dummy.prev = &dummy; for (int ii = 0; ii < 100; ii++) { act(&dummy, &arena); } return 0; }