github.com/moontrade/nogc@v0.1.7/alloc/rpmalloc/tinygo/malloc.c (about) 1 /* malloc.c - Memory allocator - Public Domain - 2016 Mattias Jansson 2 * 3 * This library provides a cross-platform lock free thread caching malloc implementation in C11. 4 * The latest source code is always available at 5 * 6 * https://github.com/mjansson/rpmalloc 7 * 8 * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions. 9 * 10 */ 11 12 // 13 // This file provides overrides for the standard library malloc entry points for C and new/delete operators for C++ 14 // It also provides automatic initialization/finalization of process and threads 15 // 16 17 #include <stddef.h> 18 19 #ifndef ARCH_64BIT 20 # if defined(__LLP64__) || defined(__LP64__) || defined(_WIN64) 21 # define ARCH_64BIT 1 22 _Static_assert(sizeof(size_t) == 8, "Data type size mismatch"); 23 _Static_assert(sizeof(void*) == 8, "Data type size mismatch"); 24 # else 25 # define ARCH_64BIT 0 26 _Static_assert(sizeof(size_t) == 4, "Data type size mismatch"); 27 _Static_assert(sizeof(void*) == 4, "Data type size mismatch"); 28 # endif 29 #endif 30 31 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) 32 #pragma GCC visibility push(default) 33 #endif 34 35 #define USE_IMPLEMENT 1 36 #define USE_INTERPOSE 0 37 #define USE_ALIAS 0 38 39 #if defined(__APPLE__) && ENABLE_PRELOAD 40 #undef USE_INTERPOSE 41 #define USE_INTERPOSE 1 42 43 typedef struct interpose_t { 44 void* new_func; 45 void* orig_func; 46 } interpose_t; 47 48 #define MAC_INTERPOSE_PAIR(newf, oldf) { (void*)newf, (void*)oldf } 49 #define MAC_INTERPOSE_SINGLE(newf, oldf) \ 50 __attribute__((used)) static const interpose_t macinterpose##newf##oldf \ 51 __attribute__ ((section("__DATA, __interpose"))) = MAC_INTERPOSE_PAIR(newf, oldf) 52 53 #endif 54 55 #if !defined(_WIN32) && !USE_INTERPOSE 56 #undef USE_IMPLEMENT 57 #undef USE_ALIAS 58 #define USE_IMPLEMENT 0 59 #define USE_ALIAS 1 60 #endif 61 62 #ifdef _MSC_VER 63 #pragma warning (disable : 4100) 64 #undef malloc 65 #undef free 66 #undef calloc 67 #define RPMALLOC_RESTRICT __declspec(restrict) 68 #else 69 #define RPMALLOC_RESTRICT 70 #endif 71 72 #if ENABLE_OVERRIDE 73 74 typedef struct rp_nothrow_t { int __dummy; } rp_nothrow_t; 75 76 #if USE_IMPLEMENT 77 78 extern inline RPMALLOC_RESTRICT void* RPMALLOC_CDECL malloc(size_t size) { return rpmalloc(size); } 79 extern inline RPMALLOC_RESTRICT void* RPMALLOC_CDECL calloc(size_t count, size_t size) { return rpcalloc(count, size); } 80 extern inline RPMALLOC_RESTRICT void* RPMALLOC_CDECL realloc(void* ptr, size_t size) { return rprealloc(ptr, size); } 81 extern inline void* RPMALLOC_CDECL reallocf(void* ptr, size_t size) { return rprealloc(ptr, size); } 82 extern inline void* RPMALLOC_CDECL aligned_alloc(size_t alignment, size_t size) { return rpaligned_alloc(alignment, size); } 83 extern inline void* RPMALLOC_CDECL memalign(size_t alignment, size_t size) { return rpmemalign(alignment, size); } 84 extern inline int RPMALLOC_CDECL posix_memalign(void** memptr, size_t alignment, size_t size) { return rpposix_memalign(memptr, alignment, size); } 85 extern inline void RPMALLOC_CDECL free(void* ptr) { rpfree(ptr); } 86 extern inline void RPMALLOC_CDECL cfree(void* ptr) { rpfree(ptr); } 87 extern inline size_t RPMALLOC_CDECL malloc_usable_size(void* ptr) { return rpmalloc_usable_size(ptr); } 88 extern inline size_t RPMALLOC_CDECL malloc_size(void* ptr) { return rpmalloc_usable_size(ptr); } 89 90 #ifdef _WIN32 91 // For Windows, #include <rpnew.h> in one source file to get the C++ operator overrides implemented in your module 92 #else 93 // Overload the C++ operators using the mangled names (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling) 94 // operators delete and delete[] 95 extern void _ZdlPv(void* p); void _ZdlPv(void* p) { rpfree(p); } 96 extern void _ZdaPv(void* p); void _ZdaPv(void* p) { rpfree(p); } 97 #if ARCH_64BIT 98 // 64-bit operators new and new[], normal and aligned 99 extern void* _Znwm(uint64_t size); void* _Znwm(uint64_t size) { return rpmalloc(size); } 100 extern void* _Znam(uint64_t size); void* _Znam(uint64_t size) { return rpmalloc(size); } 101 extern void* _Znwmm(uint64_t size, uint64_t align); void* _Znwmm(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 102 extern void* _Znamm(uint64_t size, uint64_t align); void* _Znamm(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 103 extern void* _ZnwmSt11align_val_t(uint64_t size, uint64_t align); void* _ZnwmSt11align_val_t(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 104 extern void* _ZnamSt11align_val_t(uint64_t size, uint64_t align); void* _ZnamSt11align_val_t(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 105 extern void* _ZnwmRKSt9nothrow_t(uint64_t size, rp_nothrow_t t); void* _ZnwmRKSt9nothrow_t(uint64_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 106 extern void* _ZnamRKSt9nothrow_t(uint64_t size, rp_nothrow_t t); void* _ZnamRKSt9nothrow_t(uint64_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 107 extern void* _ZnwmSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align, rp_nothrow_t t); void* _ZnwmSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 108 extern void* _ZnamSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align, rp_nothrow_t t); void* _ZnamSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 109 // 64-bit operators sized delete and delete[], normal and aligned 110 extern void _ZdlPvm(void* p, uint64_t size); void _ZdlPvm(void* p, uint64_t size) { rpfree(p); (void)sizeof(size); } 111 extern void _ZdaPvm(void* p, uint64_t size); void _ZdaPvm(void* p, uint64_t size) { rpfree(p); (void)sizeof(size); } 112 extern void _ZdlPvSt11align_val_t(void* p, uint64_t align); void _ZdlPvSt11align_val_t(void* p, uint64_t align) { rpfree(p); (void)sizeof(align); } 113 extern void _ZdaPvSt11align_val_t(void* p, uint64_t align); void _ZdaPvSt11align_val_t(void* p, uint64_t align) { rpfree(p); (void)sizeof(align); } 114 extern void _ZdlPvmSt11align_val_t(void* p, uint64_t size, uint64_t align); void _ZdlPvmSt11align_val_t(void* p, uint64_t size, uint64_t align) { rpfree(p); (void)sizeof(size); (void)sizeof(align); } 115 extern void _ZdaPvmSt11align_val_t(void* p, uint64_t size, uint64_t align); void _ZdaPvmSt11align_val_t(void* p, uint64_t size, uint64_t align) { rpfree(p); (void)sizeof(size); (void)sizeof(align); } 116 #else 117 // 32-bit operators new and new[], normal and aligned 118 extern void* _Znwj(uint32_t size); void* _Znwj(uint32_t size) { return rpmalloc(size); } 119 extern void* _Znaj(uint32_t size); void* _Znaj(uint32_t size) { return rpmalloc(size); } 120 extern void* _Znwjj(uint32_t size, uint32_t align); void* _Znwjj(uint32_t size, uint32_t align) { return rpaligned_alloc(align, size); } 121 extern void* _Znajj(uint32_t size, uint32_t align); void* _Znajj(uint32_t size, uint32_t align) { return rpaligned_alloc(align, size); } 122 extern void* _ZnwjSt11align_val_t(size_t size, size_t align); void* _ZnwjSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 123 extern void* _ZnajSt11align_val_t(size_t size, size_t align); void* _ZnajSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 124 extern void* _ZnwjRKSt9nothrow_t(size_t size, rp_nothrow_t t); void* _ZnwjRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 125 extern void* _ZnajRKSt9nothrow_t(size_t size, rp_nothrow_t t); void* _ZnajRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 126 extern void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t); void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 127 extern void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t); void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 128 // 32-bit operators sized delete and delete[], normal and aligned 129 extern void _ZdlPvj(void* p, uint64_t size); void _ZdlPvj(void* p, uint64_t size) { rpfree(p); (void)sizeof(size); } 130 extern void _ZdaPvj(void* p, uint64_t size); void _ZdaPvj(void* p, uint64_t size) { rpfree(p); (void)sizeof(size); } 131 extern void _ZdlPvSt11align_val_t(void* p, uint32_t align); void _ZdlPvSt11align_val_t(void* p, uint64_t a) { rpfree(p); (void)sizeof(align); } 132 extern void _ZdaPvSt11align_val_t(void* p, uint32_t align); void _ZdaPvSt11align_val_t(void* p, uint64_t a) { rpfree(p); (void)sizeof(align); } 133 extern void _ZdlPvjSt11align_val_t(void* p, uint32_t size, uint32_t align); void _ZdlPvjSt11align_val_t(void* p, uint64_t size, uint64_t align) { rpfree(p); (void)sizeof(size); (void)sizeof(a); } 134 extern void _ZdaPvjSt11align_val_t(void* p, uint32_t size, uint32_t align); void _ZdaPvjSt11align_val_t(void* p, uint64_t size, uint64_t align) { rpfree(p); (void)sizeof(size); (void)sizeof(a); } 135 #endif 136 #endif 137 138 #endif 139 140 #if USE_INTERPOSE 141 142 __attribute__((used)) static const interpose_t macinterpose_malloc[] 143 __attribute__ ((section("__DATA, __interpose"))) = { 144 //new and new[] 145 MAC_INTERPOSE_PAIR(rpmalloc, _Znwm), 146 MAC_INTERPOSE_PAIR(rpmalloc, _Znam), 147 //delete and delete[] 148 MAC_INTERPOSE_PAIR(rpfree, _ZdlPv), 149 MAC_INTERPOSE_PAIR(rpfree, _ZdaPv), 150 MAC_INTERPOSE_PAIR(rpmalloc, malloc), 151 MAC_INTERPOSE_PAIR(rpmalloc, calloc), 152 MAC_INTERPOSE_PAIR(rprealloc, realloc), 153 MAC_INTERPOSE_PAIR(rprealloc, reallocf), 154 #if defined(__MAC_10_15) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_15 155 MAC_INTERPOSE_PAIR(rpaligned_alloc, aligned_alloc), 156 #endif 157 MAC_INTERPOSE_PAIR(rpmemalign, memalign), 158 MAC_INTERPOSE_PAIR(rpposix_memalign, posix_memalign), 159 MAC_INTERPOSE_PAIR(rpfree, free), 160 MAC_INTERPOSE_PAIR(rpfree, cfree), 161 MAC_INTERPOSE_PAIR(rpmalloc_usable_size, malloc_usable_size), 162 MAC_INTERPOSE_PAIR(rpmalloc_usable_size, malloc_size) 163 }; 164 165 #endif 166 167 #if USE_ALIAS 168 169 #define RPALIAS(fn) __attribute__((alias(#fn), used, visibility("default"))); 170 171 // Alias the C++ operators using the mangled names (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling) 172 173 // operators delete and delete[] 174 void _ZdlPv(void* p) RPALIAS(rpfree) 175 void _ZdaPv(void* p) RPALIAS(rpfree) 176 extern inline void _ZdlPvm(void* p, size_t n) { rpfree(p); (void)sizeof(n); } 177 extern inline void _ZdaPvm(void* p, size_t n) { rpfree(p); (void)sizeof(n); } 178 extern inline void _ZdlPvSt11align_val_t(void* p, size_t a) { rpfree(p); (void)sizeof(a); } 179 extern inline void _ZdaPvSt11align_val_t(void* p, size_t a) { rpfree(p); (void)sizeof(a); } 180 extern inline void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t a) { rpfree(p); (void)sizeof(n); (void)sizeof(a); } 181 extern inline void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t a) { rpfree(p); (void)sizeof(n); (void)sizeof(a); } 182 183 #if ARCH_64BIT 184 // 64-bit operators new and new[], normal and aligned 185 void* _Znwm(uint64_t size) RPALIAS(rpmalloc) 186 void* _Znam(uint64_t size) RPALIAS(rpmalloc) 187 extern inline void* _Znwmm(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 188 extern inline void* _Znamm(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 189 extern inline void* _ZnwmSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 190 extern inline void* _ZnamSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 191 extern inline void* _ZnwmRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 192 extern inline void* _ZnamRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 193 extern inline void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 194 extern inline void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 195 #else 196 // 32-bit operators new and new[], normal and aligned 197 void* _Znwj(uint32_t size) RPALIAS(rpmalloc) 198 void* _Znaj(uint32_t size) RPALIAS(rpmalloc) 199 extern inline void* _Znwjj(uint32_t size, uint32_t align) { return rpaligned_alloc(align, size); } 200 extern inline void* _Znajj(uint32_t size, uint32_t align) { return rpaligned_alloc(align, size); } 201 extern inline void* _ZnwjSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 202 extern inline void* _ZnajSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 203 extern inline void* _ZnwjRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 204 extern inline void* _ZnajRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 205 extern inline void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 206 extern inline void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 207 #endif 208 209 void* malloc(size_t size) RPALIAS(rpmalloc) 210 void* calloc(size_t count, size_t size) RPALIAS(rpcalloc) 211 void* realloc(void* ptr, size_t size) RPALIAS(rprealloc) 212 void* reallocf(void* ptr, size_t size) RPALIAS(rprealloc) 213 void* aligned_alloc(size_t alignment, size_t size) RPALIAS(rpaligned_alloc) 214 void* memalign(size_t alignment, size_t size) RPALIAS(rpmemalign) 215 int posix_memalign(void** memptr, size_t alignment, size_t size) RPALIAS(rpposix_memalign) 216 void free(void* ptr) RPALIAS(rpfree) 217 void cfree(void* ptr) RPALIAS(rpfree) 218 #if defined(__ANDROID__) 219 size_t malloc_usable_size(const void* ptr) RPALIAS(rpmalloc_usable_size) 220 #else 221 size_t malloc_usable_size(void* ptr) RPALIAS(rpmalloc_usable_size) 222 #endif 223 size_t malloc_size(void* ptr) RPALIAS(rpmalloc_usable_size) 224 225 #endif 226 227 static inline size_t 228 _rpmalloc_page_size(void) { 229 return _memory_page_size; 230 } 231 232 extern inline void* RPMALLOC_CDECL 233 reallocarray(void* ptr, size_t count, size_t size) { 234 size_t total; 235 #if ENABLE_VALIDATE_ARGS 236 #ifdef _MSC_VER 237 int err = SizeTMult(count, size, &total); 238 if ((err != S_OK) || (total >= MAX_ALLOC_SIZE)) { 239 errno = EINVAL; 240 return 0; 241 } 242 #else 243 int err = __builtin_umull_overflow(count, size, &total); 244 if (err || (total >= MAX_ALLOC_SIZE)) { 245 errno = EINVAL; 246 return 0; 247 } 248 #endif 249 #else 250 total = count * size; 251 #endif 252 return realloc(ptr, total); 253 } 254 255 extern inline void* RPMALLOC_CDECL 256 valloc(size_t size) { 257 get_thread_heap(); 258 return rpaligned_alloc(_rpmalloc_page_size(), size); 259 } 260 261 extern inline void* RPMALLOC_CDECL 262 pvalloc(size_t size) { 263 get_thread_heap(); 264 const size_t page_size = _rpmalloc_page_size(); 265 const size_t aligned_size = ((size + page_size - 1) / page_size) * page_size; 266 #if ENABLE_VALIDATE_ARGS 267 if (aligned_size < size) { 268 errno = EINVAL; 269 return 0; 270 } 271 #endif 272 return rpaligned_alloc(_rpmalloc_page_size(), aligned_size); 273 } 274 275 #endif // ENABLE_OVERRIDE 276 277 #if ENABLE_PRELOAD 278 279 #ifdef _WIN32 280 281 #if defined(BUILD_DYNAMIC_LINK) && BUILD_DYNAMIC_LINK 282 283 extern __declspec(dllexport) BOOL WINAPI 284 DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved); 285 286 extern __declspec(dllexport) BOOL WINAPI 287 DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { 288 (void)sizeof(reserved); 289 (void)sizeof(instance); 290 if (reason == DLL_PROCESS_ATTACH) 291 rpmalloc_initialize(); 292 else if (reason == DLL_PROCESS_DETACH) 293 rpmalloc_finalize(); 294 else if (reason == DLL_THREAD_ATTACH) 295 rpmalloc_thread_initialize(); 296 else if (reason == DLL_THREAD_DETACH) 297 rpmalloc_thread_finalize(1); 298 return TRUE; 299 } 300 301 //end BUILD_DYNAMIC_LINK 302 #else 303 304 extern void 305 _global_rpmalloc_init(void) { 306 rpmalloc_set_main_thread(); 307 rpmalloc_initialize(); 308 } 309 310 #if defined(__clang__) || defined(__GNUC__) 311 312 static void __attribute__((constructor)) 313 initializer(void) { 314 _global_rpmalloc_init(); 315 } 316 317 #elif defined(_MSC_VER) 318 319 #pragma section(".CRT$XIB",read) 320 __declspec(allocate(".CRT$XIB")) void (*_rpmalloc_module_init)(void) = _global_rpmalloc_init; 321 #pragma comment(linker, "/include:_rpmalloc_module_init") 322 323 #endif 324 325 //end !BUILD_DYNAMIC_LINK 326 #endif 327 328 #else 329 330 #include <pthread.h> 331 #include <stdlib.h> 332 #include <stdint.h> 333 #include <unistd.h> 334 335 extern void 336 rpmalloc_set_main_thread(void); 337 338 static pthread_key_t destructor_key; 339 340 static void 341 thread_destructor(void*); 342 343 static void __attribute__((constructor)) 344 initializer(void) { 345 rpmalloc_set_main_thread(); 346 rpmalloc_initialize(); 347 pthread_key_create(&destructor_key, thread_destructor); 348 } 349 350 static void __attribute__((destructor)) 351 finalizer(void) { 352 rpmalloc_finalize(); 353 } 354 355 typedef struct { 356 void* (*real_start)(void*); 357 void* real_arg; 358 } thread_starter_arg; 359 360 static void* 361 thread_starter(void* argptr) { 362 thread_starter_arg* arg = argptr; 363 void* (*real_start)(void*) = arg->real_start; 364 void* real_arg = arg->real_arg; 365 rpmalloc_thread_initialize(); 366 rpfree(argptr); 367 pthread_setspecific(destructor_key, (void*)1); 368 return (*real_start)(real_arg); 369 } 370 371 static void 372 thread_destructor(void* value) { 373 (void)sizeof(value); 374 rpmalloc_thread_finalize(1); 375 } 376 377 #ifdef __APPLE__ 378 379 static int 380 pthread_create_proxy(pthread_t* thread, 381 const pthread_attr_t* attr, 382 void* (*start_routine)(void*), 383 void* arg) { 384 rpmalloc_initialize(); 385 // fprintf(stderr, "pthread_create_proxy\n"); 386 thread_starter_arg* starter_arg = rpmalloc(sizeof(thread_starter_arg)); 387 starter_arg->real_start = start_routine; 388 starter_arg->real_arg = arg; 389 return pthread_create(thread, attr, thread_starter, starter_arg); 390 } 391 392 MAC_INTERPOSE_SINGLE(pthread_create_proxy, pthread_create); 393 394 #else 395 396 #include <dlfcn.h> 397 398 int 399 pthread_create(pthread_t* thread, 400 const pthread_attr_t* attr, 401 void* (*start_routine)(void*), 402 void* arg) { 403 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ 404 defined(__APPLE__) || defined(__HAIKU__) 405 char fname[] = "pthread_create"; 406 #else 407 char fname[] = "_pthread_create"; 408 #endif 409 void* real_pthread_create = dlsym(RTLD_NEXT, fname); 410 rpmalloc_thread_initialize(); 411 thread_starter_arg* starter_arg = rpmalloc(sizeof(thread_starter_arg)); 412 starter_arg->real_start = start_routine; 413 starter_arg->real_arg = arg; 414 return (*(int (*)(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*))real_pthread_create)(thread, attr, thread_starter, starter_arg); 415 } 416 417 #endif 418 419 #endif 420 421 #endif 422 423 #if ENABLE_OVERRIDE 424 425 #if defined(__GLIBC__) && defined(__linux__) 426 427 void* __libc_malloc(size_t size) RPALIAS(rpmalloc) 428 void* __libc_calloc(size_t count, size_t size) RPALIAS(rpcalloc) 429 void* __libc_realloc(void* p, size_t size) RPALIAS(rprealloc) 430 void __libc_free(void* p) RPALIAS(rpfree) 431 void __libc_cfree(void* p) RPALIAS(rpfree) 432 void* __libc_memalign(size_t align, size_t size) RPALIAS(rpmemalign) 433 int __posix_memalign(void** p, size_t align, size_t size) RPALIAS(rpposix_memalign) 434 435 extern void* __libc_valloc(size_t size); 436 extern void* __libc_pvalloc(size_t size); 437 438 void* 439 __libc_valloc(size_t size) { 440 return valloc(size); 441 } 442 443 void* 444 __libc_pvalloc(size_t size) { 445 return pvalloc(size); 446 } 447 448 #endif 449 450 #endif 451 452 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) 453 #pragma GCC visibility pop 454 #endif