123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <stddef.h>
- #include <unistd.h>
- #include <sys/mman.h>
- #include <string.h>
-
- #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;
- }
|