#include "mem.h" #include #if !defined(_WIN32) #include #endif #include static int64_t s_tf_malloc_size; static int64_t s_uv_malloc_size; static int64_t s_tls_malloc_size; static void* _tf_alloc(int64_t* total, size_t size) { void* ptr = malloc(size + sizeof(size_t)); if (ptr) { __atomic_add_fetch(total, size, __ATOMIC_RELAXED); memcpy(ptr, &size, sizeof(size_t)); return (void*)((intptr_t)ptr + sizeof(size_t)); } else { return NULL; } } static void* _tf_realloc(int64_t* total, void* ptr, size_t size) { void* old_ptr = ptr ? (void*)((intptr_t)ptr - sizeof(size_t)) : NULL; size_t old_size = 0; if (old_ptr) { memcpy(&old_size, old_ptr, sizeof(size_t)); } void* new_ptr = realloc(old_ptr, size + sizeof(size_t)); if (new_ptr) { __atomic_add_fetch(total, (int64_t)size - (int64_t)old_size, __ATOMIC_RELAXED); memcpy(new_ptr, &size, sizeof(size_t)); return (void*)((intptr_t)new_ptr + sizeof(size_t)); } else { __atomic_sub_fetch(total, old_size, __ATOMIC_RELAXED); return NULL; } } static void _tf_free(int64_t* total, void* ptr) { if (ptr) { void* old_ptr = (void*)((intptr_t)ptr - sizeof(size_t)); size_t size = 0; memcpy(&size, old_ptr, sizeof(size_t)); __atomic_sub_fetch(total, size, __ATOMIC_RELAXED); free(old_ptr); } } static void* _tf_uv_alloc(size_t size) { return _tf_alloc(&s_uv_malloc_size, size); } static void* _tf_uv_realloc(void* ptr, size_t size) { return _tf_realloc(&s_uv_malloc_size, ptr, size); } static void* _tf_uv_calloc(size_t nmemb, size_t size) { void* ptr = calloc(1, nmemb * size + sizeof(size_t)); if (ptr) { size_t total_size = nmemb * size; __atomic_add_fetch(&s_uv_malloc_size, total_size, __ATOMIC_RELAXED); memcpy(ptr, &total_size, sizeof(size_t)); return (void*)((intptr_t)ptr + sizeof(size_t)); } else { return NULL; } } static void _tf_uv_free(void* ptr) { _tf_free(&s_uv_malloc_size, ptr); } void tf_mem_replace_uv_allocator() { uv_replace_allocator(_tf_uv_alloc, _tf_uv_realloc, _tf_uv_calloc, _tf_uv_free); } size_t tf_mem_get_uv_malloc_size() { return s_uv_malloc_size; } #if !defined(_WIN32) void* _tf_tls_alloc(size_t size, const char* file, int line) { return _tf_alloc(&s_tls_malloc_size, size); } void* _tf_tls_realloc(void* ptr, size_t size, const char* file, int line) { return _tf_realloc(&s_tls_malloc_size, ptr, size); } void _tf_tls_free(void* ptr, const char* file, int line) { _tf_free(&s_tls_malloc_size, ptr); } #endif void tf_mem_replace_tls_allocator() { #if !defined(_WIN32) CRYPTO_set_mem_functions(_tf_tls_alloc, _tf_tls_realloc, _tf_tls_free); #endif } size_t tf_mem_get_tls_malloc_size() { return s_tls_malloc_size; } void* tf_malloc(size_t size) { return _tf_alloc(&s_tf_malloc_size, size); } void* tf_realloc(void* ptr, size_t size) { return _tf_realloc(&s_tf_malloc_size, ptr, size); } void tf_free(void* ptr) { _tf_free(&s_tf_malloc_size, ptr); } char* tf_strdup(const char* string) { size_t len = strlen(string); char* buffer = tf_malloc(len + 1); memcpy(buffer, string, len + 1); return buffer; } size_t tf_mem_get_tf_malloc_size() { return s_tf_malloc_size; }