1 /*
2 * Copyright(c) 2019 Intel Corporation
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
10 */
11 #ifndef EbMalloc_h
12 #define EbMalloc_h
13 #include <stdlib.h>
14 #include <stdio.h>
15 
16 #include "EbSvtAv1Enc.h"
17 #include "EbDefinitions.h"
18 
19 #ifndef NDEBUG
20 #define DEBUG_MEMORY_USAGE
21 #endif
22 
23 void svt_print_alloc_fail(const char* file, int line);
24 
25 #ifdef DEBUG_MEMORY_USAGE
26 void svt_print_memory_usage(void);
27 void svt_increase_component_count(void);
28 void svt_decrease_component_count(void);
29 void svt_add_mem_entry(void* ptr, EbPtrType type, size_t count, const char* file, uint32_t line);
30 void svt_remove_mem_entry(void* ptr, EbPtrType type);
31 
32 #define EB_ADD_MEM_ENTRY(p, type, count) svt_add_mem_entry(p, type, count, __FILE__, __LINE__)
33 
34 #define EB_REMOVE_MEM_ENTRY(p, type) svt_remove_mem_entry(p, type);
35 
36 #else
37 #define svt_print_memory_usage() \
38     do {                         \
39     } while (0)
40 #define svt_increase_component_count() \
41     do {                               \
42     } while (0)
43 #define svt_decrease_component_count() \
44     do {                               \
45     } while (0)
46 #define EB_ADD_MEM_ENTRY(p, type, count) \
47     do {                                 \
48     } while (0)
49 #define EB_REMOVE_MEM_ENTRY(p, type) \
50     do {                             \
51     } while (0)
52 
53 #endif //DEBUG_MEMORY_USAGE
54 
55 #define EB_NO_THROW_ADD_MEM(p, size, type)            \
56     do {                                              \
57         if (!p)                                       \
58             svt_print_alloc_fail(__FILE__, __LINE__); \
59         else                                          \
60             EB_ADD_MEM_ENTRY(p, type, size);          \
61     } while (0)
62 
63 #define EB_CHECK_MEM(p)                           \
64     do {                                          \
65         if (!p)                                   \
66             return EB_ErrorInsufficientResources; \
67     } while (0)
68 
69 #define EB_ADD_MEM(p, size, type)           \
70     do {                                    \
71         EB_NO_THROW_ADD_MEM(p, size, type); \
72         EB_CHECK_MEM(p);                    \
73     } while (0)
74 
75 #define EB_NO_THROW_MALLOC(pointer, size)                \
76     do {                                                 \
77         void* malloced_p = malloc(size);                 \
78         EB_NO_THROW_ADD_MEM(malloced_p, size, EB_N_PTR); \
79         pointer = malloced_p;                            \
80     } while (0)
81 
82 #define EB_MALLOC(pointer, size)           \
83     do {                                   \
84         EB_NO_THROW_MALLOC(pointer, size); \
85         EB_CHECK_MEM(pointer);             \
86     } while (0)
87 
88 #define EB_NO_THROW_CALLOC(pointer, count, size)             \
89     do {                                                     \
90         pointer = calloc(count, size);                       \
91         EB_NO_THROW_ADD_MEM(pointer, count* size, EB_C_PTR); \
92     } while (0)
93 
94 #define EB_CALLOC(pointer, count, size)           \
95     do {                                          \
96         EB_NO_THROW_CALLOC(pointer, count, size); \
97         EB_CHECK_MEM(pointer);                    \
98     } while (0)
99 
100 #define EB_FREE(pointer)                        \
101     do {                                        \
102         EB_REMOVE_MEM_ENTRY(pointer, EB_N_PTR); \
103         free(pointer);                          \
104         pointer = NULL;                         \
105     } while (0)
106 
107 #define EB_MALLOC_ARRAY(pa, count) \
108     do { EB_MALLOC(pa, sizeof(*(pa)) * (count)); } while (0)
109 
110 #define EB_REALLOC_ARRAY(pa, count)            \
111     do {                                       \
112         size_t size = sizeof(*(pa)) * (count); \
113         void*  p    = realloc(pa, size);       \
114         if (p) {                               \
115             EB_REMOVE_MEM_ENTRY(pa, EB_N_PTR); \
116         }                                      \
117         EB_ADD_MEM(p, size, EB_N_PTR);         \
118         pa = p;                                \
119     } while (0)
120 
121 #define EB_CALLOC_ARRAY(pa, count) \
122     do { EB_CALLOC(pa, count, sizeof(*(pa))); } while (0)
123 
124 #define EB_FREE_ARRAY(pa) EB_FREE(pa);
125 
126 #define EB_ALLOC_PTR_ARRAY(pa, count) \
127     do { EB_CALLOC(pa, count, sizeof(*(pa))); } while (0)
128 
129 #define EB_FREE_PTR_ARRAY(pa, count)                           \
130     do {                                                       \
131         if (pa) {                                              \
132             for (size_t i = 0; i < count; i++) EB_FREE(pa[i]); \
133             EB_FREE(pa);                                       \
134         }                                                      \
135     } while (0)
136 
137 #define EB_MALLOC_2D(p2d, width, height)                                     \
138     do {                                                                     \
139         EB_MALLOC_ARRAY(p2d, width);                                         \
140         EB_MALLOC_ARRAY(p2d[0], (width) * (height));                         \
141         for (size_t w = 1; w < (width); w++) p2d[w] = p2d[0] + w * (height); \
142     } while (0)
143 
144 #define EB_CALLOC_2D(p2d, width, height)                                     \
145     do {                                                                     \
146         EB_MALLOC_ARRAY(p2d, width);                                         \
147         EB_CALLOC_ARRAY(p2d[0], (width) * (height));                         \
148         for (size_t w = 1; w < (width); w++) p2d[w] = p2d[0] + w * (height); \
149     } while (0)
150 
151 #define EB_FREE_2D(p2d)            \
152     do {                           \
153         if (p2d)                   \
154             EB_FREE_ARRAY(p2d[0]); \
155         EB_FREE_ARRAY(p2d);        \
156     } while (0)
157 
158 #ifdef _WIN32
159 #define EB_MALLOC_ALIGNED(pointer, size)          \
160     do {                                          \
161         pointer = _aligned_malloc(size, ALVALUE); \
162         EB_ADD_MEM(pointer, size, EB_A_PTR);      \
163     } while (0)
164 
165 #define EB_FREE_ALIGNED(pointer)                \
166     do {                                        \
167         EB_REMOVE_MEM_ENTRY(pointer, EB_A_PTR); \
168         _aligned_free(pointer);                 \
169         pointer = NULL;                         \
170     } while (0)
171 #else
172 #define EB_MALLOC_ALIGNED(pointer, size)                            \
173     do {                                                            \
174         if (posix_memalign((void**)&(pointer), ALVALUE, size) != 0) \
175             return EB_ErrorInsufficientResources;                   \
176         EB_ADD_MEM(pointer, size, EB_A_PTR);                        \
177     } while (0)
178 
179 #define EB_FREE_ALIGNED(pointer)                \
180     do {                                        \
181         EB_REMOVE_MEM_ENTRY(pointer, EB_A_PTR); \
182         free(pointer);                          \
183         pointer = NULL;                         \
184     } while (0)
185 #endif
186 
187 #define EB_MALLOC_ALIGNED_ARRAY(pa, count) EB_MALLOC_ALIGNED(pa, sizeof(*(pa)) * (count))
188 
189 #define EB_CALLOC_ALIGNED_ARRAY(pa, count)              \
190     do {                                                \
191         EB_MALLOC_ALIGNED(pa, sizeof(*(pa)) * (count)); \
192         memset(pa, 0, sizeof(*(pa)) * (count));         \
193     } while (0)
194 
195 #define EB_FREE_ALIGNED_ARRAY(pa) EB_FREE_ALIGNED(pa)
196 
197 #endif //EbMalloc_h
198