1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h>
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "tests/sys_mman.h"
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <assert.h>
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "valgrind.h"
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SUPERBLOCK_SIZE    100000
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//-------------------------------------------------------------------------
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Allocator
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//-------------------------------------------------------------------------
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid* get_superblock(void)
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void* p = mmap( 0, SUPERBLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assert(p != ((void*)(-1)));
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return p;
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// has a redzone
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void* custom_alloc(int size)
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define RZ  8
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static void* hp     = 0;    // current heap pointer
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static void* hp_lim = 0;    // maximum usable byte in current block
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int          size2  = size + RZ*2;
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void*        p;
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (hp + size2 > hp_lim) {
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      hp = get_superblock();
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      hp_lim = hp + SUPERBLOCK_SIZE - 1;
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p = hp + RZ;
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   hp += size2;
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VALGRIND_MALLOCLIKE_BLOCK( p, size, RZ, /*is_zeroed*/1 );
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return (void*)p;
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void custom_free(void* p)
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // don't actually free any memory... but mark it as freed
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VALGRIND_FREELIKE_BLOCK( p, RZ );
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef RZ
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//-------------------------------------------------------------------------
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Rest
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//-------------------------------------------------------------------------
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(void)
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int* a = custom_alloc(400);   // All sizes are divisible by 16 -- no slop.
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   custom_free(a);
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a = custom_alloc(800);
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   custom_free(a);
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a = malloc(400);
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   free(a);
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a = malloc(800);
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   free(a);
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
74