1 /*
2 * Copyright(c) 2019 Intel Corporation
3 * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 */
5 #ifndef EbMalloc_h
6 #define EbMalloc_h
7 #include <stdlib.h>
8 #include <stdio.h>
9 
10 #ifndef NDEBUG
11 #define DEBUG_MEMORY_USAGE
12 #endif
13 
14 typedef enum EB_PTRType {
15     EB_N_PTR = 0,         // malloc'd pointer
16     EB_C_PTR = 1,         // calloc'd pointer
17     EB_A_PTR = 2,         // malloc'd pointer aligned
18     EB_MUTEX = 3,         // mutex
19     EB_SEMAPHORE = 4,     // semaphore
20     EB_THREAD = 5,        // thread handle
21     EB_PTR_TYPE_TOTAL,
22 } EB_PTRType;
23 
24 #ifdef DEBUG_MEMORY_USAGE
25 void EbAddMemEntry(void* ptr,  EB_PTRType type, size_t count, const char* file, uint32_t line);
26 void EbRemoveMemEntry(void* ptr, EB_PTRType type);
27 
28 #define EB_ADD_MEM_ENTRY(p, type, count) \
29     EbAddMemEntry(p, type, count, __FILE__, __LINE__)
30 
31 #define EB_REMOVE_MEM_ENTRY(p, type) \
32     EbRemoveMemEntry(p, type);
33 
34 #else
35 
36 #define EB_ADD_MEM_ENTRY(p, type, count)
37 #define EB_REMOVE_MEM_ENTRY(p, type)
38 
39 #endif //DEBUG_MEMORY_USAGE
40 
41 #define EB_NO_THROW_ADD_MEM(p, size, type) \
42     do { \
43         if (!p) { \
44             fprintf(stderr,"allocate memory failed, at %s, L%d\n", __FILE__, __LINE__); \
45         } else { \
46             EB_ADD_MEM_ENTRY(p, type, size); \
47         } \
48     } while (0)
49 
50 #define EB_CHECK_MEM(p) \
51     do { \
52         if (!p) {\
53             return EB_ErrorInsufficientResources; \
54         } \
55     } while (0)
56 
57 #define EB_ADD_MEM(p, size, type) \
58     do { \
59         EB_NO_THROW_ADD_MEM(p, size, type); \
60         EB_CHECK_MEM(p); \
61     } while (0)
62 
63 #define EB_NO_THROW_MALLOC(pointer, size) \
64     do { \
65         void* p = malloc(size); \
66         EB_NO_THROW_ADD_MEM(p, size, EB_N_PTR); \
67         *(void**)&(pointer) = p; \
68     } while (0)
69 
70 #define EB_MALLOC(pointer, size) \
71     do { \
72         EB_NO_THROW_MALLOC(pointer, size); \
73         EB_CHECK_MEM(pointer); \
74     } while (0)
75 
76 #define EB_NO_THROW_CALLOC(pointer, count, size) \
77     do { \
78         void* p = calloc(count, size); \
79         EB_NO_THROW_ADD_MEM(p, count * size, EB_C_PTR); \
80         *(void**)&(pointer) = p; \
81     } while (0)
82 
83 #define EB_CALLOC(pointer, count, size) \
84     do { \
85         EB_NO_THROW_CALLOC(pointer, count, size); \
86         EB_CHECK_MEM(pointer); \
87     } while (0)
88 
89 #define EB_FREE(pointer) \
90     do {\
91         free(pointer); \
92         EB_REMOVE_MEM_ENTRY(pointer, EB_N_PTR); \
93         pointer = NULL; \
94     } while (0)
95 
96 
97 #define EB_MALLOC_ARRAY(pa, count) \
98     do {\
99         size_t size = sizeof(*(pa)); \
100         EB_MALLOC(pa, (count)*size); \
101     } while (0)
102 
103 #define EB_CALLOC_ARRAY(pa, count) \
104     do {\
105         size_t size = sizeof(*(pa)); \
106         EB_CALLOC(pa, count, size); \
107     } while (0)
108 
109 #define EB_FREE_ARRAY(pa) \
110     EB_FREE(pa);
111 
112 
113 #define EB_ALLOC_PTR_ARRAY(pa, count) \
114     do {\
115         size_t size = sizeof(*(pa)); \
116         EB_CALLOC(pa, count, size); \
117     } while (0)
118 
119 #define EB_FREE_PTR_ARRAY(pa, count) \
120     do {\
121         if (pa) { \
122             uint32_t i; \
123             for (i = 0; i < count; i++) { \
124                 EB_FREE(pa[i]); \
125             } \
126             EB_FREE(pa); \
127         } \
128     } while (0)
129 
130 
131 #define EB_MALLOC_2D(p2d, width, height) \
132     do {\
133         EB_MALLOC_ARRAY(p2d, width); \
134         EB_MALLOC_ARRAY(p2d[0], width * height); \
135         for (uint32_t w = 1; w < width; w++) { \
136             p2d[w] = p2d[0] + w * height; \
137         } \
138     } while (0)
139 
140 #define EB_CALLOC_2D(p2d, width, height) \
141     do {\
142         EB_MALLOC_ARRAY(p2d, width); \
143         EB_CALLOC_ARRAY(p2d[0], width * height); \
144         for (uint32_t w = 1; w < width; w++) { \
145              p2d[w] = p2d[0] + w * height; \
146         } \
147     } while (0)
148 
149 #define EB_FREE_2D(p2d) \
150     do { \
151         if (p2d) EB_FREE_ARRAY(p2d[0]); \
152         EB_FREE_ARRAY(p2d); \
153     } while (0)
154 
155 
156 #ifdef _WIN32
157 #define EB_MALLOC_ALIGNED(pointer, size) \
158     do {\
159         void* p = _aligned_malloc(size,ALVALUE); \
160         EB_ADD_MEM(p, size, EB_A_PTR); \
161         *(void**)&(pointer) = p; \
162     } while (0)
163 
164 #define EB_FREE_ALIGNED(pointer) \
165     do { \
166         _aligned_free(pointer); \
167         EB_REMOVE_MEM_ENTRY(pointer, EB_A_PTR); \
168         pointer = NULL; \
169     } while (0)
170 #else
171 #define EB_MALLOC_ALIGNED(pointer, size) \
172     do {\
173         if (posix_memalign((void**)(&(pointer)), ALVALUE, size) != 0) \
174             return EB_ErrorInsufficientResources; \
175         EB_ADD_MEM(pointer, size, EB_A_PTR); \
176     } while (0)
177 
178 #define EB_FREE_ALIGNED(pointer) \
179     do { \
180         free(pointer); \
181         EB_REMOVE_MEM_ENTRY(pointer, EB_A_PTR); \
182         pointer = NULL; \
183     } while (0)
184 #endif
185 
186 
187 #define EB_MALLOC_ALIGNED_ARRAY(pa, count) \
188     EB_MALLOC_ALIGNED(pa, sizeof(*(pa))*(count))
189 
190 #define EB_CALLOC_ALIGNED_ARRAY(pa, count) \
191     do { \
192         size_t size = sizeof(*(pa))*(count); \
193         EB_MALLOC_ALIGNED(pa, size); \
194         memset(pa, 0, size); \
195     } while (0)
196 
197 #define EB_FREE_ALIGNED_ARRAY(pa) \
198     EB_FREE_ALIGNED(pa)
199 
200 
201 void EbPrintMemoryUsage();
202 void EbIncreaseComponentCount();
203 void EbDecreaseComponentCount();
204 
205 
206 #endif //EbMalloc_h
207