drd: Add a consistency check
[valgrind.git] / memcheck / tests / mempool.c
blob2bd53183d9a717153fa0be81315b8c25f3d57fcd
1 #include <unistd.h>
2 #include "tests/sys_mman.h"
3 #include <assert.h>
4 #include <stdlib.h>
6 #include "../memcheck.h"
8 #define SUPERBLOCK_SIZE 100000
9 #define REDZONE_SIZE 8
11 static const int USE_MMAP = 0;
13 typedef struct _level_list
15 struct _level_list *next;
16 char *where;
17 // Padding ensures the struct is the same size on 32-bit and 64-bit
18 // machines.
19 char padding[16 - 2*sizeof(char*)];
20 } level_list;
22 typedef struct _pool {
23 char *mem;
24 char *where;
25 level_list *levels;
26 int size, left;
27 // Padding ensures the struct is the same size on 32-bit and 64-bit
28 // machines.
29 char padding[24 - 3*sizeof(char*)];
30 } pool;
32 pool *make_pool()
34 pool *p;
36 if(USE_MMAP) {
37 p = (pool *)mmap(0, sizeof(pool), PROT_READ|PROT_WRITE|PROT_EXEC,
38 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
39 p->where = p->mem = (char *)mmap(NULL, SUPERBLOCK_SIZE,
40 PROT_READ|PROT_WRITE|PROT_EXEC,
41 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
42 } else {
43 p = (pool *)malloc(sizeof(pool));
44 p->where = p->mem = (char *)malloc(SUPERBLOCK_SIZE);
47 p->size = p->left = SUPERBLOCK_SIZE;
48 p->levels = NULL;
49 (void) VALGRIND_MAKE_MEM_NOACCESS(p->where, SUPERBLOCK_SIZE);
50 return p;
53 void push(pool *p)
55 level_list *l;
57 if(USE_MMAP)
58 l = (level_list *)mmap(0, sizeof(level_list),
59 PROT_READ|PROT_WRITE|PROT_EXEC,
60 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
61 else
62 l = (level_list *)malloc(sizeof(level_list));
64 l->next = p->levels;
65 l->where = p->where;
66 VALGRIND_CREATE_MEMPOOL(l->where, REDZONE_SIZE, 0);
67 p->levels = l;
70 void pop(pool *p)
72 level_list *l = p->levels;
73 p->levels = l->next;
74 VALGRIND_DESTROY_MEMPOOL(l->where);
75 (void) VALGRIND_MAKE_MEM_NOACCESS(l->where, p->where-l->where);
76 p->where = l->where;
77 if(USE_MMAP)
78 munmap(l, sizeof(level_list));
79 else
80 free(l);
83 void destroy_pool(pool *p)
85 level_list *l = p->levels;
87 while(l) {
88 pop(p);
90 if(USE_MMAP) {
91 munmap(p->mem, SUPERBLOCK_SIZE);
92 munmap(p, sizeof(pool));
93 } else {
94 free(p->mem);
95 free(p);
99 char *allocate(pool *p, int size)
101 char *where;
102 p->left -= size + (REDZONE_SIZE*2);
103 where = p->where + REDZONE_SIZE;
104 p->where += size + (REDZONE_SIZE*2);
105 VALGRIND_MEMPOOL_ALLOC(p->levels->where, where, size);
106 return where;
109 //-------------------------------------------------------------------------
110 // Rest
111 //-------------------------------------------------------------------------
113 void test(void)
115 char *x1, *x2, *x3, *x4, *x5;
117 pool *p = make_pool();
119 push(p);
121 x1 = allocate(p, 10);
122 x2 = allocate(p, 20);
123 push(p);
124 x3 = allocate(p, 10);
125 x4 = allocate(p, 20);
127 *x1 = 'a'; // valid
128 *x2 = 'b'; // valid
130 x1[-1] = 'h'; // invalid
131 x1[10] = 'i'; // invalid
133 pop(p);
135 *x3 = 'c'; // invalid
136 *x4 = 'd'; // invalid
138 *x1 = 'e'; // valid
139 *x2 = 'f'; // valid
141 x5 = allocate(p, 10);
143 *x5 = 'g'; // valid
145 // pop(p);
147 // *x5 = 'g'; // invalid
149 // destroy_pool(p);
152 int main(void)
154 test();
155 return 0;