sanitizer_persistent_allocator.h revision 1.1.1.1
1//===-- sanitizer_persistent_allocator.h ------------------------*- C++ -*-===// 2// 3// This file is distributed under the University of Illinois Open Source 4// License. See LICENSE.TXT for details. 5// 6//===----------------------------------------------------------------------===// 7// 8// A fast memory allocator that does not support free() nor realloc(). 9// All allocations are forever. 10//===----------------------------------------------------------------------===// 11#ifndef SANITIZER_PERSISTENT_ALLOCATOR_H 12#define SANITIZER_PERSISTENT_ALLOCATOR_H 13 14#include "sanitizer_internal_defs.h" 15#include "sanitizer_mutex.h" 16#include "sanitizer_atomic.h" 17#include "sanitizer_common.h" 18 19namespace __sanitizer { 20 21class PersistentAllocator { 22 public: 23 void *alloc(uptr size); 24 25 private: 26 void *tryAlloc(uptr size); 27 StaticSpinMutex mtx; // Protects alloc of new blocks for region allocator. 28 atomic_uintptr_t region_pos; // Region allocator for Node's. 29 atomic_uintptr_t region_end; 30}; 31 32inline void *PersistentAllocator::tryAlloc(uptr size) { 33 // Optimisic lock-free allocation, essentially try to bump the region ptr. 34 for (;;) { 35 uptr cmp = atomic_load(®ion_pos, memory_order_acquire); 36 uptr end = atomic_load(®ion_end, memory_order_acquire); 37 if (cmp == 0 || cmp + size > end) return 0; 38 if (atomic_compare_exchange_weak(®ion_pos, &cmp, cmp + size, 39 memory_order_acquire)) 40 return (void *)cmp; 41 } 42} 43 44inline void *PersistentAllocator::alloc(uptr size) { 45 // First, try to allocate optimisitically. 46 void *s = tryAlloc(size); 47 if (s) return s; 48 // If failed, lock, retry and alloc new superblock. 49 SpinMutexLock l(&mtx); 50 for (;;) { 51 s = tryAlloc(size); 52 if (s) return s; 53 atomic_store(®ion_pos, 0, memory_order_relaxed); 54 uptr allocsz = 64 * 1024; 55 if (allocsz < size) allocsz = size; 56 uptr mem = (uptr)MmapOrDie(allocsz, "stack depot"); 57 atomic_store(®ion_end, mem + allocsz, memory_order_release); 58 atomic_store(®ion_pos, mem, memory_order_release); 59 } 60} 61 62extern PersistentAllocator thePersistentAllocator; 63inline void *PersistentAlloc(uptr sz) { 64 return thePersistentAllocator.alloc(sz); 65} 66 67} // namespace __sanitizer 68 69#endif // SANITIZER_PERSISTENT_ALLOCATOR_H 70