You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.3 KiB

#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;
}