diff options
author | dim <dim@FreeBSD.org> | 2015-01-08 19:47:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-01-08 19:47:10 +0000 |
commit | ab328f15cea04a45750ef56019d2b3d971e033f3 (patch) | |
tree | f47eabbd2a48be6d6fec3ddeeefae5b4aeb87dbc /contrib/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h | |
parent | 8189659be8e499f37c87fdd05ef5ec9f88619d56 (diff) | |
parent | 2f1c5cc1039d86db0037cb086bd58f4b90dc6f66 (diff) | |
download | FreeBSD-src-ab328f15cea04a45750ef56019d2b3d971e033f3.zip FreeBSD-src-ab328f15cea04a45750ef56019d2b3d971e033f3.tar.gz |
Update compiler-rt to trunk r224034. This brings a number of new
builtins, and also the various sanitizers. Support for these will be
added in a later commit.
Diffstat (limited to 'contrib/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h')
-rw-r--r-- | contrib/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h new file mode 100644 index 0000000..326406b --- /dev/null +++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h @@ -0,0 +1,71 @@ +//===-- sanitizer_persistent_allocator.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// A fast memory allocator that does not support free() nor realloc(). +// All allocations are forever. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_PERSISTENT_ALLOCATOR_H +#define SANITIZER_PERSISTENT_ALLOCATOR_H + +#include "sanitizer_internal_defs.h" +#include "sanitizer_mutex.h" +#include "sanitizer_atomic.h" +#include "sanitizer_common.h" + +namespace __sanitizer { + +class PersistentAllocator { + public: + void *alloc(uptr size); + + private: + void *tryAlloc(uptr size); + StaticSpinMutex mtx; // Protects alloc of new blocks for region allocator. + atomic_uintptr_t region_pos; // Region allocator for Node's. + atomic_uintptr_t region_end; +}; + +inline void *PersistentAllocator::tryAlloc(uptr size) { + // Optimisic lock-free allocation, essentially try to bump the region ptr. + for (;;) { + uptr cmp = atomic_load(®ion_pos, memory_order_acquire); + uptr end = atomic_load(®ion_end, memory_order_acquire); + if (cmp == 0 || cmp + size > end) return 0; + if (atomic_compare_exchange_weak(®ion_pos, &cmp, cmp + size, + memory_order_acquire)) + return (void *)cmp; + } +} + +inline void *PersistentAllocator::alloc(uptr size) { + // First, try to allocate optimisitically. + void *s = tryAlloc(size); + if (s) return s; + // If failed, lock, retry and alloc new superblock. + SpinMutexLock l(&mtx); + for (;;) { + s = tryAlloc(size); + if (s) return s; + atomic_store(®ion_pos, 0, memory_order_relaxed); + uptr allocsz = 64 * 1024; + if (allocsz < size) allocsz = size; + uptr mem = (uptr)MmapOrDie(allocsz, "stack depot"); + atomic_store(®ion_end, mem + allocsz, memory_order_release); + atomic_store(®ion_pos, mem, memory_order_release); + } +} + +extern PersistentAllocator thePersistentAllocator; +inline void *PersistentAlloc(uptr sz) { + return thePersistentAllocator.alloc(sz); +} + +} // namespace __sanitizer + +#endif // SANITIZER_PERSISTENT_ALLOCATOR_H |