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 //===----------------------------------------------------------------------===//
11 #ifndef SANITIZER_PERSISTENT_ALLOCATOR_H
12 #define SANITIZER_PERSISTENT_ALLOCATOR_H
14 #include "sanitizer_internal_defs.h"
15 #include "sanitizer_mutex.h"
16 #include "sanitizer_atomic.h"
17 #include "sanitizer_common.h"
19 namespace __sanitizer
{
21 class PersistentAllocator
{
23 void *alloc(uptr size
);
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
;
32 inline void *PersistentAllocator::tryAlloc(uptr size
) {
33 // Optimisic lock-free allocation, essentially try to bump the region ptr.
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
))
44 inline void *PersistentAllocator::alloc(uptr size
) {
45 // First, try to allocate optimisitically.
46 void *s
= tryAlloc(size
);
48 // If failed, lock, retry and alloc new superblock.
49 SpinMutexLock
l(&mtx
);
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
);
62 extern PersistentAllocator thePersistentAllocator
;
63 inline void *PersistentAlloc(uptr sz
) {
64 return thePersistentAllocator
.alloc(sz
);
67 } // namespace __sanitizer
69 #endif // SANITIZER_PERSISTENT_ALLOCATOR_H