#include <unistd.h> #include "tests/sys_mman.h" #include <assert.h> #include <stdlib.h> #include "valgrind.h" #define SUPERBLOCK_SIZE 100000 //------------------------------------------------------------------------- // Allocator //------------------------------------------------------------------------- void* get_superblock(void) { void* p = mmap( 0, SUPERBLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 ); assert(p != ((void*)(-1))); return p; } // has a redzone static void* custom_alloc(int size) { #define RZ 8 static void* hp = 0; // current heap pointer static void* hp_lim = 0; // maximum usable byte in current block int size2 = size + RZ*2; void* p; if (hp + size2 > hp_lim) { hp = get_superblock(); hp_lim = hp + SUPERBLOCK_SIZE - 1; } p = hp + RZ; hp += size2; VALGRIND_MALLOCLIKE_BLOCK( p, size, RZ, /*is_zeroed*/1 ); return (void*)p; } static void custom_free(void* p) { // don't actually free any memory... but mark it as freed VALGRIND_FREELIKE_BLOCK( p, RZ ); } #undef RZ //------------------------------------------------------------------------- // Rest //------------------------------------------------------------------------- int main(void) { int* a = custom_alloc(400); // All sizes are divisible by 16 -- no slop. custom_free(a); a = custom_alloc(800); custom_free(a); a = malloc(400); free(a); a = malloc(800); free(a); return 0; }