00001 // Copyright 2017 The Abseil Authors. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // https://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 // 00015 00016 #ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ 00017 #define ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ 00018 00019 // A simple thread-safe memory allocator that does not depend on 00020 // mutexes or thread-specific data. It is intended to be used 00021 // sparingly, and only when malloc() would introduce an unwanted 00022 // dependency, such as inside the heap-checker, or the Mutex 00023 // implementation. 00024 00025 // IWYU pragma: private, include "base/low_level_alloc.h" 00026 00027 #include <sys/types.h> 00028 00029 #include <cstdint> 00030 00031 #include "absl/base/attributes.h" 00032 #include "absl/base/config.h" 00033 00034 // LowLevelAlloc requires that the platform support low-level 00035 // allocation of virtual memory. Platforms lacking this cannot use 00036 // LowLevelAlloc. 00037 #ifdef ABSL_LOW_LEVEL_ALLOC_MISSING 00038 #error ABSL_LOW_LEVEL_ALLOC_MISSING cannot be directly set 00039 #elif !defined(ABSL_HAVE_MMAP) && !defined(_WIN32) 00040 #define ABSL_LOW_LEVEL_ALLOC_MISSING 1 00041 #endif 00042 00043 // Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows or 00044 // asm.js / WebAssembly. 00045 // See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html 00046 // for more information. 00047 #ifdef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 00048 #error ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING cannot be directly set 00049 #elif defined(_WIN32) || defined(__asmjs__) || defined(__wasm__) 00050 #define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1 00051 #endif 00052 00053 #include <cstddef> 00054 00055 #include "absl/base/port.h" 00056 00057 namespace absl { 00058 namespace base_internal { 00059 00060 class LowLevelAlloc { 00061 public: 00062 struct Arena; // an arena from which memory may be allocated 00063 00064 // Returns a pointer to a block of at least "request" bytes 00065 // that have been newly allocated from the specific arena. 00066 // for Alloc() call the DefaultArena() is used. 00067 // Returns 0 if passed request==0. 00068 // Does not return 0 under other circumstances; it crashes if memory 00069 // is not available. 00070 static void *Alloc(size_t request) ABSL_ATTRIBUTE_SECTION(malloc_hook); 00071 static void *AllocWithArena(size_t request, Arena *arena) 00072 ABSL_ATTRIBUTE_SECTION(malloc_hook); 00073 00074 // Deallocates a region of memory that was previously allocated with 00075 // Alloc(). Does nothing if passed 0. "s" must be either 0, 00076 // or must have been returned from a call to Alloc() and not yet passed to 00077 // Free() since that call to Alloc(). The space is returned to the arena 00078 // from which it was allocated. 00079 static void Free(void *s) ABSL_ATTRIBUTE_SECTION(malloc_hook); 00080 00081 // ABSL_ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free 00082 // are to put all callers of MallocHook::Invoke* in this module 00083 // into special section, 00084 // so that MallocHook::GetCallerStackTrace can function accurately. 00085 00086 // Create a new arena. 00087 // The root metadata for the new arena is allocated in the 00088 // meta_data_arena; the DefaultArena() can be passed for meta_data_arena. 00089 // These values may be ored into flags: 00090 enum { 00091 // Report calls to Alloc() and Free() via the MallocHook interface. 00092 // Set in the DefaultArena. 00093 kCallMallocHook = 0x0001, 00094 00095 #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 00096 // Make calls to Alloc(), Free() be async-signal-safe. Not set in 00097 // DefaultArena(). Not supported on all platforms. 00098 kAsyncSignalSafe = 0x0002, 00099 #endif 00100 }; 00101 // Construct a new arena. The allocation of the underlying metadata honors 00102 // the provided flags. For example, the call NewArena(kAsyncSignalSafe) 00103 // is itself async-signal-safe, as well as generatating an arena that provides 00104 // async-signal-safe Alloc/Free. 00105 static Arena *NewArena(int32_t flags); 00106 00107 // Destroys an arena allocated by NewArena and returns true, 00108 // provided no allocated blocks remain in the arena. 00109 // If allocated blocks remain in the arena, does nothing and 00110 // returns false. 00111 // It is illegal to attempt to destroy the DefaultArena(). 00112 static bool DeleteArena(Arena *arena); 00113 00114 // The default arena that always exists. 00115 static Arena *DefaultArena(); 00116 00117 private: 00118 LowLevelAlloc(); // no instances 00119 }; 00120 00121 } // namespace base_internal 00122 } // namespace absl 00123 00124 #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_