1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 16 #ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ 17 #define ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ 18 19 // A simple thread-safe memory allocator that does not depend on 20 // mutexes or thread-specific data. It is intended to be used 21 // sparingly, and only when malloc() would introduce an unwanted 22 // dependency, such as inside the heap-checker, or the Mutex 23 // implementation. 24 25 // IWYU pragma: private, include "base/low_level_alloc.h" 26 27 #include <sys/types.h> 28 29 #include <cstdint> 30 31 #include "absl/base/attributes.h" 32 #include "absl/base/config.h" 33 34 // LowLevelAlloc requires that the platform support low-level 35 // allocation of virtual memory. Platforms lacking this cannot use 36 // LowLevelAlloc. 37 #ifdef ABSL_LOW_LEVEL_ALLOC_MISSING 38 #error ABSL_LOW_LEVEL_ALLOC_MISSING cannot be directly set 39 #elif !defined(ABSL_HAVE_MMAP) && !defined(_WIN32) 40 #define ABSL_LOW_LEVEL_ALLOC_MISSING 1 41 #endif 42 43 // Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows or 44 // asm.js / WebAssembly. 45 // See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html 46 // for more information. 47 #ifdef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 48 #error ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING cannot be directly set 49 #elif defined(_WIN32) || defined(__asmjs__) || defined(__wasm__) || \ 50 defined(__hexagon__) 51 #define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1 52 #endif 53 54 #include <cstddef> 55 56 #include "absl/base/port.h" 57 58 namespace absl { 59 ABSL_NAMESPACE_BEGIN 60 namespace base_internal { 61 62 class LowLevelAlloc { 63 public: 64 struct Arena; // an arena from which memory may be allocated 65 66 // Returns a pointer to a block of at least "request" bytes 67 // that have been newly allocated from the specific arena. 68 // for Alloc() call the DefaultArena() is used. 69 // Returns 0 if passed request==0. 70 // Does not return 0 under other circumstances; it crashes if memory 71 // is not available. 72 static void *Alloc(size_t request) ABSL_ATTRIBUTE_SECTION(malloc_hook); 73 static void *AllocWithArena(size_t request, Arena *arena) 74 ABSL_ATTRIBUTE_SECTION(malloc_hook); 75 76 // Deallocates a region of memory that was previously allocated with 77 // Alloc(). Does nothing if passed 0. "s" must be either 0, 78 // or must have been returned from a call to Alloc() and not yet passed to 79 // Free() since that call to Alloc(). The space is returned to the arena 80 // from which it was allocated. 81 static void Free(void *s) ABSL_ATTRIBUTE_SECTION(malloc_hook); 82 83 // ABSL_ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free 84 // are to put all callers of MallocHook::Invoke* in this module 85 // into special section, 86 // so that MallocHook::GetCallerStackTrace can function accurately. 87 88 // Create a new arena. 89 // The root metadata for the new arena is allocated in the 90 // meta_data_arena; the DefaultArena() can be passed for meta_data_arena. 91 // These values may be ored into flags: 92 enum { 93 // Report calls to Alloc() and Free() via the MallocHook interface. 94 // Set in the DefaultArena. 95 kCallMallocHook = 0x0001, 96 97 #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 98 // Make calls to Alloc(), Free() be async-signal-safe. Not set in 99 // DefaultArena(). Not supported on all platforms. 100 kAsyncSignalSafe = 0x0002, 101 #endif 102 }; 103 // Construct a new arena. The allocation of the underlying metadata honors 104 // the provided flags. For example, the call NewArena(kAsyncSignalSafe) 105 // is itself async-signal-safe, as well as generatating an arena that provides 106 // async-signal-safe Alloc/Free. 107 static Arena *NewArena(uint32_t flags); 108 109 // Destroys an arena allocated by NewArena and returns true, 110 // provided no allocated blocks remain in the arena. 111 // If allocated blocks remain in the arena, does nothing and 112 // returns false. 113 // It is illegal to attempt to destroy the DefaultArena(). 114 static bool DeleteArena(Arena *arena); 115 116 // The default arena that always exists. 117 static Arena *DefaultArena(); 118 119 private: 120 LowLevelAlloc(); // no instances 121 }; 122 123 } // namespace base_internal 124 ABSL_NAMESPACE_END 125 } // namespace absl 126 127 #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ 128