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