1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: |
3 | #ident "$Id$" |
4 | /*====== |
5 | This file is part of PerconaFT. |
6 | |
7 | |
8 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
9 | |
10 | PerconaFT is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License, version 2, |
12 | as published by the Free Software Foundation. |
13 | |
14 | PerconaFT is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | GNU General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
21 | |
22 | ---------------------------------------- |
23 | |
24 | PerconaFT is free software: you can redistribute it and/or modify |
25 | it under the terms of the GNU Affero General Public License, version 3, |
26 | as published by the Free Software Foundation. |
27 | |
28 | PerconaFT is distributed in the hope that it will be useful, |
29 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
31 | GNU Affero General Public License for more details. |
32 | |
33 | You should have received a copy of the GNU Affero General Public License |
34 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
35 | ======= */ |
36 | |
37 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
38 | |
39 | #pragma once |
40 | |
41 | #include <stdlib.h> |
42 | #include <toku_portability.h> |
43 | |
44 | /* Percona memory allocation functions and macros. |
45 | * These are functions for malloc and free */ |
46 | |
47 | int toku_memory_startup(void) __attribute__((constructor)); |
48 | void toku_memory_shutdown(void) __attribute__((destructor)); |
49 | |
50 | /* Generally: errno is set to 0 or a value to indicate problems. */ |
51 | |
52 | // Everything should call toku_malloc() instead of malloc(), and toku_calloc() instead of calloc() |
53 | // That way the tests can can, e.g., replace the malloc function using toku_set_func_malloc(). |
54 | void *toku_calloc(size_t nmemb, size_t size) __attribute__((__visibility__("default" ))); |
55 | void *toku_xcalloc(size_t nmemb, size_t size) __attribute__((__visibility__("default" ))); |
56 | void *toku_malloc(size_t size) __attribute__((__visibility__("default" ))); |
57 | void *toku_malloc_aligned(size_t alignment, size_t size) __attribute__((__visibility__("default" ))); |
58 | |
59 | // xmalloc aborts instead of return NULL if we run out of memory |
60 | void *toku_xmalloc(size_t size) __attribute__((__visibility__("default" ))); |
61 | void *toku_xrealloc(void*, size_t size) __attribute__((__visibility__("default" ))); |
62 | void *toku_xmalloc_aligned(size_t alignment, size_t size) __attribute__((__visibility__("default" ))); |
63 | // Effect: Perform a os_malloc_aligned(size) with the additional property that the returned pointer is a multiple of ALIGNMENT. |
64 | // Fail with a resource_assert if the allocation fails (don't return an error code). |
65 | // If the alloc_aligned function has been set then call it instead. |
66 | // Requires: alignment is a power of two. |
67 | |
68 | void toku_free(void*) __attribute__((__visibility__("default" ))); |
69 | void *toku_realloc(void *, size_t size) __attribute__((__visibility__("default" ))); |
70 | void *toku_realloc_aligned(size_t alignment, void *p, size_t size) __attribute__((__visibility__("default" ))); |
71 | // Effect: Perform a os_realloc_aligned(alignment, p, size) which has the additional property that the returned pointer is a multiple of ALIGNMENT. |
72 | // If the malloc_aligned function has been set then call it instead. |
73 | // Requires: alignment is a power of two. |
74 | |
75 | size_t toku_malloc_usable_size(void *p) __attribute__((__visibility__("default" ))); |
76 | |
77 | /* MALLOC is a macro that helps avoid a common error: |
78 | * Suppose I write |
79 | * struct foo *x = malloc(sizeof(struct foo)); |
80 | * That works fine. But if I change it to this, I've probably made an mistake: |
81 | * struct foo *x = malloc(sizeof(struct bar)); |
82 | * It can get worse, since one might have something like |
83 | * struct foo *x = malloc(sizeof(struct foo *)) |
84 | * which looks reasonable, but it allocoates enough to hold a pointer instead of the amount needed for the struct. |
85 | * So instead, write |
86 | * struct foo *MALLOC(x); |
87 | * and you cannot go wrong. |
88 | */ |
89 | #define MALLOC(v) CAST_FROM_VOIDP(v, toku_malloc(sizeof(*v))) |
90 | /* MALLOC_N is like calloc(Except no 0ing of data): It makes an array. Write |
91 | * int *MALLOC_N(5,x); |
92 | * to make an array of 5 integers. |
93 | */ |
94 | #define MALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_malloc((n)*sizeof(*v))) |
95 | #define MALLOC_N_ALIGNED(align, n, v) CAST_FROM_VOIDP(v, toku_malloc_aligned((align), (n)*sizeof(*v))) |
96 | |
97 | |
98 | //CALLOC_N is like calloc with auto-figuring out size of members |
99 | #define CALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_calloc((n), sizeof(*v))) |
100 | |
101 | #define CALLOC(v) CALLOC_N(1,v) |
102 | |
103 | #define REALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_realloc(v, (n)*sizeof(*v))) |
104 | #define REALLOC_N_ALIGNED(align, n,v) CAST_FROM_VOIDP(v, toku_realloc_aligned((align), v, (n)*sizeof(*v))) |
105 | |
106 | // XMALLOC macros are like MALLOC except they abort if the operation fails |
107 | #define XMALLOC(v) CAST_FROM_VOIDP(v, toku_xmalloc(sizeof(*v))) |
108 | #define XMALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xmalloc((n)*sizeof(*v))) |
109 | #define XCALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xcalloc((n), (sizeof(*v)))) |
110 | #define XCALLOC(v) XCALLOC_N(1,(v)) |
111 | #define XREALLOC(v,s) CAST_FROM_VOIDP(v, toku_xrealloc(v, s)) |
112 | #define XREALLOC_N(n,v) CAST_FROM_VOIDP(v, toku_xrealloc(v, (n)*sizeof(*v))) |
113 | |
114 | #define XMALLOC_N_ALIGNED(align, n, v) CAST_FROM_VOIDP(v, toku_xmalloc_aligned((align), (n)*sizeof(*v))) |
115 | |
116 | #define XMEMDUP(dst, src) CAST_FROM_VOIDP(dst, toku_xmemdup(src, sizeof(*src))) |
117 | #define XMEMDUP_N(dst, src, len) CAST_FROM_VOIDP(dst, toku_xmemdup(src, len)) |
118 | |
119 | // ZERO_ARRAY writes zeroes to a stack-allocated array |
120 | #define ZERO_ARRAY(o) do { memset((o), 0, sizeof (o)); } while (0) |
121 | // ZERO_STRUCT writes zeroes to a stack-allocated struct |
122 | #define ZERO_STRUCT(o) do { memset(&(o), 0, sizeof (o)); } while (0) |
123 | |
124 | /* Copy memory. Analogous to strdup() */ |
125 | void *toku_memdup (const void *v, size_t len); |
126 | /* Toku-version of strdup. Use this so that it calls toku_malloc() */ |
127 | char *toku_strdup (const char *s) __attribute__((__visibility__("default" ))); |
128 | /* Toku-version of strndup. Use this so that it calls toku_malloc() */ |
129 | char *toku_strndup(const char *s, size_t n) |
130 | __attribute__((__visibility__("default" ))); |
131 | /* Copy memory. Analogous to strdup() Crashes instead of returning NULL */ |
132 | void *toku_xmemdup (const void *v, size_t len) __attribute__((__visibility__("default" ))); |
133 | /* Toku-version of strdup. Use this so that it calls toku_xmalloc() Crashes instead of returning NULL */ |
134 | char *toku_xstrdup (const char *s) __attribute__((__visibility__("default" ))); |
135 | |
136 | void toku_malloc_cleanup (void); /* Before exiting, call this function to free up any internal data structures from toku_malloc. Otherwise valgrind will complain of memory leaks. */ |
137 | |
138 | /* Check to see if everything malloc'd was free. Might be a no-op depending on how memory.c is configured. */ |
139 | void toku_memory_check_all_free (void); |
140 | /* Check to see if memory is "sane". Might be a no-op. Probably better to simply use valgrind. */ |
141 | void toku_do_memory_check(void); |
142 | |
143 | typedef void *(*malloc_fun_t)(size_t); |
144 | typedef void (*free_fun_t)(void*); |
145 | typedef void *(*realloc_fun_t)(void*,size_t); |
146 | typedef void *(*malloc_aligned_fun_t)(size_t /*alignment*/, size_t /*size*/); |
147 | typedef void *(*realloc_aligned_fun_t)(size_t /*alignment*/, void */*pointer*/, size_t /*size*/); |
148 | |
149 | void toku_set_func_malloc(malloc_fun_t f); |
150 | void toku_set_func_xmalloc_only(malloc_fun_t f); |
151 | void toku_set_func_malloc_only(malloc_fun_t f); |
152 | void toku_set_func_realloc(realloc_fun_t f); |
153 | void toku_set_func_xrealloc_only(realloc_fun_t f); |
154 | void toku_set_func_realloc_only(realloc_fun_t f); |
155 | void toku_set_func_free(free_fun_t f); |
156 | |
157 | typedef struct memory_status { |
158 | uint64_t malloc_count; // number of malloc operations |
159 | uint64_t free_count; // number of free operations |
160 | uint64_t realloc_count; // number of realloc operations |
161 | uint64_t malloc_fail; // number of malloc operations that failed |
162 | uint64_t realloc_fail; // number of realloc operations that failed |
163 | uint64_t requested; // number of bytes requested |
164 | uint64_t used; // number of bytes used (requested + overhead), obtained from malloc_usable_size() |
165 | uint64_t freed; // number of bytes freed; |
166 | uint64_t max_requested_size; // largest attempted allocation size |
167 | uint64_t last_failed_size; // size of the last failed allocation attempt |
168 | volatile uint64_t max_in_use; // maximum memory footprint (used - freed), approximate (not worth threadsafety overhead for exact) |
169 | const char *mallocator_version; |
170 | uint64_t mmap_threshold; |
171 | } LOCAL_MEMORY_STATUS_S, *LOCAL_MEMORY_STATUS; |
172 | |
173 | void toku_memory_get_status(LOCAL_MEMORY_STATUS s); |
174 | |
175 | // Effect: Like toku_memory_footprint, except instead of passing p, |
176 | // we pass toku_malloc_usable_size(p). |
177 | size_t (size_t touched, size_t usable); |
178 | |
179 | // Effect: Return an estimate how how much space an object is using, possibly by |
180 | // using toku_malloc_usable_size(p). |
181 | // If p is NULL then returns 0. |
182 | size_t (void * p, size_t touched); |
183 | |