1
/* Copyright (C) 2010 Philip Ashmore (contact@philipashmore.com) */
2
/* License: LGPLv3. See LICENSE.txt for the full license. */
4
/* THIS IS NOT A DISK BASED IMPLEMENTATION */
14
#define TREEDB_SOMBRERO_ALLOC_OMIT_pack_unpack
15
#include "treedb-malloc-defines.h"
17
extern A16(runtime_t) A16(runtime_init);
18
extern A32(runtime_t) A32(runtime_init);
19
extern LG(runtime_t) LG(runtime_init);
20
extern treedb_malloc_allocator_runtime_t treedb_malloc_allocator_runtime_init;
22
treedb_allocator_runtime create_treedb_allocator(int free_emptied)
24
treedb_allocator_runtime h =
25
(treedb_allocator_runtime)malloc(sizeof(treedb_malloc_allocator_runtime_t));
28
*h = treedb_malloc_allocator_runtime_init;
29
h->free_emptied_heaps = free_emptied;
32
TreedbFreeResult free_treedb_allocator(treedb_allocator_runtime h)
35
return eTreedbFreeBadHeap;
36
/* The lists and the heap tree use the heap runtime wrappers to store their
37
nodes so free the heaps and it all disappears. */
38
treedb_malloc_heap_node_ref_ptr_t t;
39
t.heap_node = (HEAP(node_ptr_t))(h->heap.m_head);
40
TreedbFreeResult ret = eTreedbFreeSuccess, ret2;
42
treedb_malloc_heap_node_ref_ptr_t t2;
43
t2.heap_node = (HEAP(node_ptr_t))(t.heap_node->m_heap_next);
45
case eMallocHeapNodeTree16:
46
ret2 = A16(free_heap)(h, t.a16);
48
case eMallocHeapNodeTree32:
49
ret2 = A32(free_heap)(h, t.a32);
51
case eMallocHeapNodeLarge:
52
ret2 = LG(free_heap)(h, t.large);
55
ret2 = eTreedbFreeBadHeap;
65
/******************************************************************************/
67
/******************************************************************************/
68
A16(runtime_wrap_ptr_t) A16(new_heap)(treedb_allocator_runtime h)
71
A16(runtime_wrap_ptr_t) p = (A16(runtime_wrap_ptr_t))
72
malloc(sizeof(A16(runtime_wrap_t)));
75
p->type = eMallocHeapNodeTree16;
76
p->runtime = A16(runtime_init);
77
p->runtime.m_pBase = mmap(0, 64 * 1024
78
, PROT_READ | PROT_WRITE
79
, MAP_PRIVATE | MAP_ANONYMOUS
82
if(p->runtime.m_pBase == (char *)-1) {
83
p->runtime.m_pBase = 0;
87
TreedbInitResult res = A16(init_memory)(& p->runtime, sizeof(A16(treedb_t)));
88
if(res != eTreedbInitSuccess) {
89
munmap((char *)(p->runtime.m_pBase), 64 * 1024);
93
/* Resize the free node so it reaches the end of this heap. */
94
A16(AvlAllocator_node_ptr_t) node
95
= (A16(AvlAllocator_node_ptr_t))(p->runtime.m_pBase
96
+ p->runtime.m_pTreedb->m_allocator.m_free.m_head);
97
/* It's the only free node so we don't have to remove it and re-insert it
98
because of the key change. */
99
node->m_uLength += 64 * 1024 - TREEDB_PAGE_SIZE;
100
p->m_uSize = 64 * 1024;
103
TreedbFreeResult A16(free_heap)(treedb_allocator_runtime h, A16(runtime_wrap_ptr_t) p)
106
TreedbFreeResult ret = eTreedbFreeSuccess;
107
if(p->runtime.m_pBase)
108
munmap((char *)(p->runtime.m_pBase), 64 * 1024);
110
ret = eTreedbFreeBadHeap;
114
A16(AvlAllocator_node_ptr_t) A16(alloc_node)
115
( A16(runtime_ptr_t) runtime
118
char * p = (char *)treedb_malloc_allocator16_malloc(runtime, size);
119
return (A16(AvlAllocator_node_ptr_t))
120
(p - V3C_ROUND_UP_T2(uintptr_t, sizeof(A16(AvlAllocator_node_t)), 2));
123
/******************************************************************************/
125
/******************************************************************************/
126
A32(runtime_wrap_ptr_t) A32(new_heap)(treedb_allocator_runtime h)
129
A32(runtime_wrap_ptr_t) p = (A32(runtime_wrap_ptr_t))
130
malloc(sizeof(A32(runtime_wrap_t)));
133
p->type = eMallocHeapNodeTree32;
134
p->runtime = A32(runtime_init);
135
p->runtime.m_pBase = mmap(0, 4UL * 1024UL * 1024UL
136
, PROT_READ | PROT_WRITE
137
, MAP_PRIVATE | MAP_ANONYMOUS
140
if(p->runtime.m_pBase == (char *)-1) {
143
printf("A32(new_heap) : mmap failed : EINVAL.\n");
146
printf("A32(new_heap) : mmap failed : EACCES.\n");
149
printf("A32(new_heap) : mmap failed : ENOMEM.\n");
152
printf("A32(new_heap) : mmap failed : ENODEV.\n");
155
printf("A32(new_heap) : mmap failed : ENOEXEC.\n");
158
printf("A32(new_heap) : mmap failed : <?>.\n");
161
p->runtime.m_pBase = 0;
165
TreedbInitResult res = A32(init_memory)(& p->runtime, sizeof(A32(treedb_t)));
166
if(res != eTreedbInitSuccess) {
167
munmap((char *)(p->runtime.m_pBase), 4UL * 1024UL * 1024UL);
171
/* Resize the free node so it reaches the end of this heap. */
172
A32(AvlAllocator_node_ptr_t) node
173
= (A32(AvlAllocator_node_ptr_t))(p->runtime.m_pBase
174
+ p->runtime.m_pTreedb->m_allocator.m_free.m_head);
175
/* It's the only free node so we don't have to remove it and re-insert it
176
because of the key change. */
178
+= 4UL * 1024UL * 1024UL - TREEDB_PAGE_SIZE;
179
p->m_uSize = 4UL * 1024UL * 1024UL;
182
TreedbFreeResult A32(free_heap)(treedb_allocator_runtime h, A32(runtime_wrap_ptr_t) p)
185
TreedbFreeResult ret = eTreedbFreeSuccess;
186
if(p->runtime.m_pBase)
187
munmap((char *)(p->runtime.m_pBase), 4UL * 1024UL * 1024UL);
189
ret = eTreedbFreeBadHeap;
193
A32(AvlAllocator_node_ptr_t) A32(alloc_node)
194
( A32(runtime_ptr_t) runtime
197
char * p = (char *)treedb_malloc_allocator32_malloc(runtime, size);
198
return (A32(AvlAllocator_node_ptr_t))
199
(p - V3C_ROUND_UP_T2(uintptr_t, sizeof(A32(AvlAllocator_node_t)), 4));
202
/******************************************************************************/
203
/* Large Allocation */
204
/******************************************************************************/
205
LG(runtime_wrap_ptr_t) LG(new_heap)(treedb_allocator_runtime h
209
LG(runtime_wrap_ptr_t) p = (LG(runtime_wrap_ptr_t))
210
malloc(sizeof(LG(runtime_wrap_t)));
213
p->type = eMallocHeapNodeLarge;
214
p->runtime = LG(runtime_init);
215
p->runtime.m_pBase = mmap(0, size + sizeof(uint64_t)
216
, PROT_READ | PROT_WRITE
217
, MAP_PRIVATE | MAP_ANONYMOUS
220
if(p->runtime.m_pBase == (char *)-1) {
221
p->runtime.m_pBase = 0;
225
/* This demo get's a bit scraggy here :) */
226
p->runtime.m_pData->length = p->m_uSize = size;
229
TreedbFreeResult LG(free_heap)(treedb_allocator_runtime h, LG(runtime_wrap_ptr_t) p)
232
TreedbFreeResult ret = eTreedbFreeSuccess;
233
if(p->runtime.m_pBase)
234
munmap((char *)(p->runtime.m_pBase), p->runtime.m_pData->length + sizeof(uint64_t));
236
ret = eTreedbFreeBadHeap;
240
void * LG(realloc)(treedb_allocator_runtime h, LG(runtime_wrap_ptr_t) p, size_t new_size)
243
char * q = mremap((char *)(p->runtime.m_pBase), p->runtime.m_pData->length
244
, new_size + sizeof(uint64_t)
248
p->runtime.m_pData->length = p->m_uSize = new_size;