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