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 #define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1 51 #endif 52 53 #include <cstddef> 54 55 #include "absl/base/port.h" 56 57 namespace absl { 58 ABSL_NAMESPACE_BEGIN 59 namespace base_internal { 60 61 class LowLevelAlloc { 62 public: 63 struct Arena; // an arena from which memory may be allocated 64 65 // Returns a pointer to a block of at least "request" bytes 66 // that have been newly allocated from the specific arena. 67 // for Alloc() call the DefaultArena() is used. 68 // Returns 0 if passed request==0. 69 // Does not return 0 under other circumstances; it crashes if memory 70 // is not available. 71 static void *Alloc(size_t request) ABSL_ATTRIBUTE_SECTION(malloc_hook); 72 static void *AllocWithArena(size_t request, Arena *arena) 73 ABSL_ATTRIBUTE_SECTION(malloc_hook); 74 75 // Deallocates a region of memory that was previously allocated with 76 // Alloc(). Does nothing if passed 0. "s" must be either 0, 77 // or must have been returned from a call to Alloc() and not yet passed to 78 // Free() since that call to Alloc(). The space is returned to the arena 79 // from which it was allocated. 80 static void Free(void *s) ABSL_ATTRIBUTE_SECTION(malloc_hook); 81 82 // ABSL_ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free 83 // are to put all callers of MallocHook::Invoke* in this module 84 // into special section, 85 // so that MallocHook::GetCallerStackTrace can function accurately. 86 87 // Create a new arena. 88 // The root metadata for the new arena is allocated in the 89 // meta_data_arena; the DefaultArena() can be passed for meta_data_arena. 90 // These values may be ored into flags: 91 enum { 92 // Report calls to Alloc() and Free() via the MallocHook interface. 93 // Set in the DefaultArena. 94 kCallMallocHook = 0x0001, 95 96 #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 97 // Make calls to Alloc(), Free() be async-signal-safe. Not set in 98 // DefaultArena(). Not supported on all platforms. 99 kAsyncSignalSafe = 0x0002, 100 #endif 101 }; 102 // Construct a new arena. The allocation of the underlying metadata honors 103 // the provided flags. For example, the call NewArena(kAsyncSignalSafe) 104 // is itself async-signal-safe, as well as generatating an arena that provides 105 // async-signal-safe Alloc/Free. 106 static Arena *NewArena(int32_t flags); 107 108 // Destroys an arena allocated by NewArena and returns true, 109 // provided no allocated blocks remain in the arena. 110 // If allocated blocks remain in the arena, does nothing and 111 // returns false. 112 // It is illegal to attempt to destroy the DefaultArena(). 113 static bool DeleteArena(Arena *arena); 114 115 // The default arena that always exists. 116 static Arena *DefaultArena(); 117 118 private: 119 LowLevelAlloc(); // no instances 120 }; 121 122 } // namespace base_internal 123 ABSL_NAMESPACE_END 124 } // namespace absl 125 126 #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ 127