1 /**
2 * @file heap_memory.cc
3 *
4 * @section LICENSE
5 *
6 * The MIT License
7 *
8 * @copyright Copyright (c) 2021 TileDB, Inc.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
27 *
28 * @section DESCRIPTION
29 *
30 * Implements TileDB-variants of dynamic (heap) memory allocation routines.
31 */
32
33 #include <cstdlib>
34
35 #include "tiledb/common/heap_memory.h"
36 #include "tiledb/common/heap_profiler.h"
37
38 namespace tiledb {
39 namespace common {
40
41 // Protects against races between memory management APIs
42 // and the HeapProfiler API.
43 std::recursive_mutex __tdb_heap_mem_lock;
44
tiledb_malloc(const size_t size,const std::string & label)45 void* tiledb_malloc(const size_t size, const std::string& label) {
46 if (!heap_profiler.enabled()) {
47 return std::malloc(size);
48 }
49
50 std::unique_lock<std::recursive_mutex> ul(__tdb_heap_mem_lock);
51
52 void* const p = std::malloc(size);
53
54 if (!p)
55 heap_profiler.dump_and_terminate();
56
57 heap_profiler.record_alloc(p, size, label);
58
59 return p;
60 }
61
tiledb_calloc(const size_t num,const size_t size,const std::string & label)62 void* tiledb_calloc(
63 const size_t num, const size_t size, const std::string& label) {
64 if (!heap_profiler.enabled()) {
65 return std::calloc(num, size);
66 }
67
68 std::unique_lock<std::recursive_mutex> ul(__tdb_heap_mem_lock);
69
70 void* const p = std::calloc(num, size);
71
72 if (!p)
73 heap_profiler.dump_and_terminate();
74
75 heap_profiler.record_alloc(p, num * size, label);
76
77 return p;
78 }
79
tiledb_realloc(void * const p,const size_t size,const std::string & label)80 void* tiledb_realloc(
81 void* const p, const size_t size, const std::string& label) {
82 if (!heap_profiler.enabled()) {
83 return std::realloc(p, size);
84 }
85
86 std::unique_lock<std::recursive_mutex> ul(__tdb_heap_mem_lock);
87
88 void* const p_realloc = std::realloc(p, size);
89
90 if (!p_realloc)
91 heap_profiler.dump_and_terminate();
92
93 heap_profiler.record_dealloc(p);
94 heap_profiler.record_alloc(p_realloc, size, label);
95
96 return p_realloc;
97 }
98
tiledb_free(void * const p)99 void tiledb_free(void* const p) {
100 if (!heap_profiler.enabled()) {
101 free(p);
102 return;
103 }
104
105 std::unique_lock<std::recursive_mutex> ul(__tdb_heap_mem_lock);
106
107 free(p);
108 heap_profiler.record_dealloc(p);
109 }
110
111 } // namespace common
112 } // namespace tiledb
113