1
by brian
clean slate |
1 |
/******************************************************
|
2 |
The memory management
|
|
3 |
||
4 |
(c) 1994, 1995 Innobase Oy
|
|
5 |
||
6 |
Created 6/9/1994 Heikki Tuuri
|
|
7 |
*******************************************************/
|
|
8 |
||
9 |
#ifndef mem0mem_h
|
|
10 |
#define mem0mem_h
|
|
11 |
||
12 |
#include "univ.i" |
|
13 |
#include "ut0mem.h" |
|
14 |
#include "ut0byte.h" |
|
15 |
#include "ut0ut.h" |
|
16 |
#include "ut0rnd.h" |
|
17 |
#include "sync0sync.h" |
|
18 |
#include "ut0lst.h" |
|
19 |
#include "mach0data.h" |
|
20 |
||
21 |
/* -------------------- MEMORY HEAPS ----------------------------- */
|
|
22 |
||
23 |
/* The info structure stored at the beginning of a heap block */
|
|
24 |
typedef struct mem_block_info_struct mem_block_info_t; |
|
25 |
||
26 |
/* A block of a memory heap consists of the info structure
|
|
27 |
followed by an area of memory */
|
|
28 |
typedef mem_block_info_t mem_block_t; |
|
29 |
||
30 |
/* A memory heap is a nonempty linear list of memory blocks */
|
|
31 |
typedef mem_block_t mem_heap_t; |
|
32 |
||
33 |
/* Types of allocation for memory heaps: DYNAMIC means allocation from the
|
|
34 |
dynamic memory pool of the C compiler, BUFFER means allocation from the
|
|
35 |
buffer pool; the latter method is used for very big heaps */
|
|
36 |
||
37 |
#define MEM_HEAP_DYNAMIC 0 /* the most common type */ |
|
38 |
#define MEM_HEAP_BUFFER 1
|
|
39 |
#define MEM_HEAP_BTR_SEARCH 2 /* this flag can optionally be |
|
40 |
ORed to MEM_HEAP_BUFFER, in which
|
|
41 |
case heap->free_block is used in
|
|
42 |
some cases for memory allocations,
|
|
43 |
and if it's NULL, the memory
|
|
44 |
allocation functions can return
|
|
45 |
NULL. */
|
|
46 |
||
47 |
/* The following start size is used for the first block in the memory heap if
|
|
48 |
the size is not specified, i.e., 0 is given as the parameter in the call of
|
|
49 |
create. The standard size is the maximum (payload) size of the blocks used for
|
|
50 |
allocations of small buffers. */
|
|
51 |
||
52 |
#define MEM_BLOCK_START_SIZE 64
|
|
53 |
#define MEM_BLOCK_STANDARD_SIZE 8000
|
|
54 |
||
55 |
/* If a memory heap is allowed to grow into the buffer pool, the following
|
|
56 |
is the maximum size for a single allocated buffer: */
|
|
57 |
#define MEM_MAX_ALLOC_IN_BUF (UNIV_PAGE_SIZE - 200)
|
|
58 |
||
59 |
/**********************************************************************
|
|
60 |
Initializes the memory system. */
|
|
61 |
||
62 |
void
|
|
63 |
mem_init( |
|
64 |
/*=====*/
|
|
65 |
ulint size); /* in: common pool size in bytes */ |
|
66 |
/******************************************************************
|
|
67 |
Use this macro instead of the corresponding function! Macro for memory
|
|
68 |
heap creation. */
|
|
69 |
||
70 |
#define mem_heap_create(N) mem_heap_create_func(\
|
|
71 |
(N), NULL, MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
|
|
72 |
/******************************************************************
|
|
73 |
Use this macro instead of the corresponding function! Macro for memory
|
|
74 |
heap creation. */
|
|
75 |
||
76 |
#define mem_heap_create_in_buffer(N) mem_heap_create_func(\
|
|
77 |
(N), NULL, MEM_HEAP_BUFFER, __FILE__, __LINE__)
|
|
78 |
/******************************************************************
|
|
79 |
Use this macro instead of the corresponding function! Macro for memory
|
|
80 |
heap creation. */
|
|
81 |
||
82 |
#define mem_heap_create_in_btr_search(N) mem_heap_create_func(\
|
|
83 |
(N), NULL, MEM_HEAP_BTR_SEARCH | MEM_HEAP_BUFFER,\
|
|
84 |
__FILE__, __LINE__)
|
|
85 |
/******************************************************************
|
|
86 |
Use this macro instead of the corresponding function! Macro for fast
|
|
87 |
memory heap creation. An initial block of memory B is given by the
|
|
88 |
caller, N is its size, and this memory block is not freed by
|
|
89 |
mem_heap_free. See the parameter comment in mem_heap_create_func below. */
|
|
90 |
||
91 |
#define mem_heap_fast_create(N, B) mem_heap_create_func(\
|
|
92 |
(N), (B), MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
|
|
93 |
||
94 |
/******************************************************************
|
|
95 |
Use this macro instead of the corresponding function! Macro for memory
|
|
96 |
heap freeing. */
|
|
97 |
||
98 |
#define mem_heap_free(heap) mem_heap_free_func(\
|
|
99 |
(heap), __FILE__, __LINE__)
|
|
100 |
/*********************************************************************
|
|
101 |
NOTE: Use the corresponding macros instead of this function. Creates a
|
|
102 |
memory heap. For debugging purposes, takes also the file name and line as
|
|
103 |
arguments. */
|
|
104 |
UNIV_INLINE
|
|
105 |
mem_heap_t* |
|
106 |
mem_heap_create_func( |
|
107 |
/*=================*/
|
|
108 |
/* out, own: memory heap, NULL if
|
|
109 |
did not succeed (only possible for
|
|
110 |
MEM_HEAP_BTR_SEARCH type heaps)*/
|
|
111 |
ulint n, /* in: desired start block size, |
|
112 |
this means that a single user buffer
|
|
113 |
of size n will fit in the block,
|
|
114 |
0 creates a default size block;
|
|
115 |
if init_block is not NULL, n tells
|
|
116 |
its size in bytes */
|
|
117 |
void* init_block, /* in: if very fast creation is |
|
118 |
wanted, the caller can reserve some
|
|
119 |
memory from its stack, for example,
|
|
120 |
and pass it as the the initial block
|
|
121 |
to the heap: then no OS call of malloc
|
|
122 |
is needed at the creation. CAUTION:
|
|
123 |
the caller must make sure the initial
|
|
124 |
block is not unintentionally erased
|
|
125 |
(if allocated in the stack), before
|
|
126 |
the memory heap is explicitly freed. */
|
|
127 |
ulint type, /* in: heap type */ |
|
128 |
const char* file_name, /* in: file name where created */ |
|
129 |
ulint line); /* in: line where created */ |
|
130 |
/*********************************************************************
|
|
131 |
NOTE: Use the corresponding macro instead of this function. Frees the space
|
|
132 |
occupied by a memory heap. In the debug version erases the heap memory
|
|
133 |
blocks. */
|
|
134 |
UNIV_INLINE
|
|
135 |
void
|
|
136 |
mem_heap_free_func( |
|
137 |
/*===============*/
|
|
138 |
mem_heap_t* heap, /* in, own: heap to be freed */ |
|
139 |
const char* file_name, /* in: file name where freed */ |
|
140 |
ulint line); /* in: line where freed */ |
|
141 |
/*******************************************************************
|
|
142 |
Allocates n bytes of memory from a memory heap. */
|
|
143 |
UNIV_INLINE
|
|
144 |
void* |
|
145 |
mem_heap_alloc( |
|
146 |
/*===========*/
|
|
147 |
/* out: allocated storage, NULL if did not
|
|
148 |
succeed (only possible for
|
|
149 |
MEM_HEAP_BTR_SEARCH type heaps) */
|
|
150 |
mem_heap_t* heap, /* in: memory heap */ |
|
151 |
ulint n); /* in: number of bytes; if the heap is allowed |
|
152 |
to grow into the buffer pool, this must be
|
|
153 |
<= MEM_MAX_ALLOC_IN_BUF */
|
|
154 |
/*********************************************************************
|
|
155 |
Returns a pointer to the heap top. */
|
|
156 |
UNIV_INLINE
|
|
157 |
byte* |
|
158 |
mem_heap_get_heap_top( |
|
159 |
/*==================*/
|
|
160 |
/* out: pointer to the heap top */
|
|
161 |
mem_heap_t* heap); /* in: memory heap */ |
|
162 |
/*********************************************************************
|
|
163 |
Frees the space in a memory heap exceeding the pointer given. The
|
|
164 |
pointer must have been acquired from mem_heap_get_heap_top. The first
|
|
165 |
memory block of the heap is not freed. */
|
|
166 |
UNIV_INLINE
|
|
167 |
void
|
|
168 |
mem_heap_free_heap_top( |
|
169 |
/*===================*/
|
|
170 |
mem_heap_t* heap, /* in: heap from which to free */ |
|
171 |
byte* old_top);/* in: pointer to old top of heap */ |
|
172 |
/*********************************************************************
|
|
173 |
Empties a memory heap. The first memory block of the heap is not freed. */
|
|
174 |
UNIV_INLINE
|
|
175 |
void
|
|
176 |
mem_heap_empty( |
|
177 |
/*===========*/
|
|
178 |
mem_heap_t* heap); /* in: heap to empty */ |
|
179 |
/*********************************************************************
|
|
180 |
Returns a pointer to the topmost element in a memory heap.
|
|
181 |
The size of the element must be given. */
|
|
182 |
UNIV_INLINE
|
|
183 |
void* |
|
184 |
mem_heap_get_top( |
|
185 |
/*=============*/
|
|
186 |
/* out: pointer to the topmost element */
|
|
187 |
mem_heap_t* heap, /* in: memory heap */ |
|
188 |
ulint n); /* in: size of the topmost element */ |
|
189 |
/*********************************************************************
|
|
190 |
Frees the topmost element in a memory heap.
|
|
191 |
The size of the element must be given. */
|
|
192 |
UNIV_INLINE
|
|
193 |
void
|
|
194 |
mem_heap_free_top( |
|
195 |
/*==============*/
|
|
196 |
mem_heap_t* heap, /* in: memory heap */ |
|
197 |
ulint n); /* in: size of the topmost element */ |
|
198 |
/*********************************************************************
|
|
199 |
Returns the space in bytes occupied by a memory heap. */
|
|
200 |
UNIV_INLINE
|
|
201 |
ulint
|
|
202 |
mem_heap_get_size( |
|
203 |
/*==============*/
|
|
204 |
mem_heap_t* heap); /* in: heap */ |
|
205 |
/******************************************************************
|
|
206 |
Use this macro instead of the corresponding function!
|
|
207 |
Macro for memory buffer allocation */
|
|
208 |
||
209 |
#define mem_alloc(N) mem_alloc_func((N), __FILE__, __LINE__)
|
|
210 |
/******************************************************************
|
|
211 |
Use this macro instead of the corresponding function!
|
|
212 |
Macro for memory buffer allocation */
|
|
213 |
||
214 |
#define mem_alloc_noninline(N) mem_alloc_func_noninline(\
|
|
215 |
(N), __FILE__, __LINE__)
|
|
216 |
/*******************************************************************
|
|
217 |
NOTE: Use the corresponding macro instead of this function.
|
|
218 |
Allocates a single buffer of memory from the dynamic memory of
|
|
219 |
the C compiler. Is like malloc of C. The buffer must be freed
|
|
220 |
with mem_free. */
|
|
221 |
UNIV_INLINE
|
|
222 |
void* |
|
223 |
mem_alloc_func( |
|
224 |
/*===========*/
|
|
225 |
/* out, own: free storage */
|
|
226 |
ulint n, /* in: desired number of bytes */ |
|
227 |
const char* file_name, /* in: file name where created */ |
|
228 |
ulint line /* in: line where created */ |
|
229 |
);
|
|
230 |
/*******************************************************************
|
|
231 |
NOTE: Use the corresponding macro instead of this function.
|
|
232 |
Allocates a single buffer of memory from the dynamic memory of
|
|
233 |
the C compiler. Is like malloc of C. The buffer must be freed
|
|
234 |
with mem_free. */
|
|
235 |
||
236 |
void* |
|
237 |
mem_alloc_func_noninline( |
|
238 |
/*=====================*/
|
|
239 |
/* out, own: free storage */
|
|
240 |
ulint n, /* in: desired number of bytes */ |
|
241 |
const char* file_name, /* in: file name where created */ |
|
242 |
ulint line /* in: line where created */ |
|
243 |
);
|
|
244 |
/******************************************************************
|
|
245 |
Use this macro instead of the corresponding function!
|
|
246 |
Macro for memory buffer freeing */
|
|
247 |
||
248 |
#define mem_free(PTR) mem_free_func((PTR), __FILE__, __LINE__)
|
|
249 |
/*******************************************************************
|
|
250 |
NOTE: Use the corresponding macro instead of this function.
|
|
251 |
Frees a single buffer of storage from
|
|
252 |
the dynamic memory of C compiler. Similar to free of C. */
|
|
253 |
UNIV_INLINE
|
|
254 |
void
|
|
255 |
mem_free_func( |
|
256 |
/*==========*/
|
|
257 |
void* ptr, /* in, own: buffer to be freed */ |
|
258 |
const char* file_name, /* in: file name where created */ |
|
259 |
ulint line /* in: line where created */ |
|
260 |
);
|
|
261 |
||
262 |
/**************************************************************************
|
|
263 |
Duplicates a NUL-terminated string. */
|
|
264 |
UNIV_INLINE
|
|
265 |
char* |
|
266 |
mem_strdup( |
|
267 |
/*=======*/
|
|
268 |
/* out, own: a copy of the string,
|
|
269 |
must be deallocated with mem_free */
|
|
270 |
const char* str); /* in: string to be copied */ |
|
271 |
/**************************************************************************
|
|
272 |
Makes a NUL-terminated copy of a nonterminated string. */
|
|
273 |
UNIV_INLINE
|
|
274 |
char* |
|
275 |
mem_strdupl( |
|
276 |
/*========*/
|
|
277 |
/* out, own: a copy of the string,
|
|
278 |
must be deallocated with mem_free */
|
|
279 |
const char* str, /* in: string to be copied */ |
|
280 |
ulint len); /* in: length of str, in bytes */ |
|
281 |
||
282 |
/**************************************************************************
|
|
283 |
Duplicates a NUL-terminated string, allocated from a memory heap. */
|
|
284 |
||
285 |
char* |
|
286 |
mem_heap_strdup( |
|
287 |
/*============*/
|
|
288 |
/* out, own: a copy of the string */
|
|
289 |
mem_heap_t* heap, /* in: memory heap where string is allocated */ |
|
290 |
const char* str); /* in: string to be copied */ |
|
291 |
/**************************************************************************
|
|
292 |
Makes a NUL-terminated copy of a nonterminated string,
|
|
293 |
allocated from a memory heap. */
|
|
294 |
UNIV_INLINE
|
|
295 |
char* |
|
296 |
mem_heap_strdupl( |
|
297 |
/*=============*/
|
|
298 |
/* out, own: a copy of the string */
|
|
299 |
mem_heap_t* heap, /* in: memory heap where string is allocated */ |
|
300 |
const char* str, /* in: string to be copied */ |
|
301 |
ulint len); /* in: length of str, in bytes */ |
|
302 |
||
303 |
/**************************************************************************
|
|
304 |
Concatenate two strings and return the result, using a memory heap. */
|
|
305 |
||
306 |
char* |
|
307 |
mem_heap_strcat( |
|
308 |
/*============*/
|
|
309 |
/* out, own: the result */
|
|
310 |
mem_heap_t* heap, /* in: memory heap where string is allocated */ |
|
311 |
const char* s1, /* in: string 1 */ |
|
312 |
const char* s2); /* in: string 2 */ |
|
313 |
||
314 |
/**************************************************************************
|
|
315 |
Duplicate a block of data, allocated from a memory heap. */
|
|
316 |
||
317 |
void* |
|
318 |
mem_heap_dup( |
|
319 |
/*=========*/
|
|
320 |
/* out, own: a copy of the data */
|
|
321 |
mem_heap_t* heap, /* in: memory heap where copy is allocated */ |
|
322 |
const void* data, /* in: data to be copied */ |
|
323 |
ulint len); /* in: length of data, in bytes */ |
|
324 |
||
325 |
/**************************************************************************
|
|
326 |
Concatenate two memory blocks and return the result, using a memory heap. */
|
|
327 |
||
328 |
void* |
|
329 |
mem_heap_cat( |
|
330 |
/*=========*/
|
|
331 |
/* out, own: the result */
|
|
332 |
mem_heap_t* heap, /* in: memory heap where result is allocated */ |
|
333 |
const void* b1, /* in: block 1 */ |
|
334 |
ulint len1, /* in: length of b1, in bytes */ |
|
335 |
const void* b2, /* in: block 2 */ |
|
336 |
ulint len2); /* in: length of b2, in bytes */ |
|
337 |
||
338 |
/********************************************************************
|
|
339 |
A simple (s)printf replacement that dynamically allocates the space for the
|
|
340 |
formatted string from the given heap. This supports a very limited set of
|
|
341 |
the printf syntax: types 's' and 'u' and length modifier 'l' (which is
|
|
342 |
required for the 'u' type). */
|
|
343 |
||
344 |
char* |
|
345 |
mem_heap_printf( |
|
346 |
/*============*/
|
|
347 |
/* out: heap-allocated formatted string */
|
|
348 |
mem_heap_t* heap, /* in: memory heap */ |
|
349 |
const char* format, /* in: format string */ |
|
350 |
...) __attribute__ ((format (printf, 2, 3))); |
|
351 |
||
352 |
#ifdef MEM_PERIODIC_CHECK
|
|
353 |
/**********************************************************************
|
|
354 |
Goes through the list of all allocated mem blocks, checks their magic
|
|
355 |
numbers, and reports possible corruption. */
|
|
356 |
||
357 |
void
|
|
358 |
mem_validate_all_blocks(void); |
|
359 |
/*=========================*/
|
|
360 |
#endif
|
|
361 |
||
362 |
/*#######################################################################*/
|
|
363 |
||
364 |
/* The info header of a block in a memory heap */
|
|
365 |
||
366 |
struct mem_block_info_struct { |
|
367 |
ulint magic_n;/* magic number for debugging */ |
|
368 |
char file_name[8];/* file name where the mem heap was created */ |
|
369 |
ulint line; /* line number where the mem heap was created */ |
|
370 |
UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the |
|
371 |
the list this is the base node of the list of blocks;
|
|
372 |
in subsequent blocks this is undefined */
|
|
373 |
UT_LIST_NODE_T(mem_block_t) list; /* This contains pointers to next |
|
374 |
and prev in the list. The first block allocated
|
|
375 |
to the heap is also the first block in this list,
|
|
376 |
though it also contains the base node of the list. */
|
|
377 |
ulint len; /* physical length of this block in bytes */ |
|
378 |
ulint type; /* type of heap: MEM_HEAP_DYNAMIC, or |
|
379 |
MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */
|
|
380 |
ibool init_block; /* TRUE if this is the first block used in fast |
|
381 |
creation of a heap: the memory will be freed
|
|
382 |
by the creator, not by mem_heap_free */
|
|
383 |
ulint free; /* offset in bytes of the first free position for |
|
384 |
user data in the block */
|
|
385 |
ulint start; /* the value of the struct field 'free' at the |
|
386 |
creation of the block */
|
|
387 |
byte* free_block; |
|
388 |
/* if the MEM_HEAP_BTR_SEARCH bit is set in type,
|
|
389 |
and this is the heap root, this can contain an
|
|
390 |
allocated buffer frame, which can be appended as a
|
|
391 |
free block to the heap, if we need more space;
|
|
392 |
otherwise, this is NULL */
|
|
393 |
#ifdef MEM_PERIODIC_CHECK
|
|
394 |
UT_LIST_NODE_T(mem_block_t) mem_block_list; |
|
395 |
/* List of all mem blocks allocated; protected
|
|
396 |
by the mem_comm_pool mutex */
|
|
397 |
#endif
|
|
398 |
};
|
|
399 |
||
400 |
#define MEM_BLOCK_MAGIC_N 764741555
|
|
401 |
#define MEM_FREED_BLOCK_MAGIC_N 547711122
|
|
402 |
||
403 |
/* Header size for a memory heap block */
|
|
404 |
#define MEM_BLOCK_HEADER_SIZE ut_calc_align(sizeof(mem_block_info_t),\
|
|
405 |
UNIV_MEM_ALIGNMENT)
|
|
406 |
#include "mem0dbg.h" |
|
407 |
||
408 |
#ifndef UNIV_NONINL
|
|
409 |
#include "mem0mem.ic" |
|
410 |
#endif
|
|
411 |
||
412 |
#endif
|