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