summaryrefslogtreecommitdiffstats
path: root/contrib/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-01-08 19:47:10 +0000
committerdim <dim@FreeBSD.org>2015-01-08 19:47:10 +0000
commitab328f15cea04a45750ef56019d2b3d971e033f3 (patch)
treef47eabbd2a48be6d6fec3ddeeefae5b4aeb87dbc /contrib/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h
parent8189659be8e499f37c87fdd05ef5ec9f88619d56 (diff)
parent2f1c5cc1039d86db0037cb086bd58f4b90dc6f66 (diff)
downloadFreeBSD-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.h71
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(&region_pos, memory_order_acquire);
+ uptr end = atomic_load(&region_end, memory_order_acquire);
+ if (cmp == 0 || cmp + size > end) return 0;
+ if (atomic_compare_exchange_weak(&region_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(&region_pos, 0, memory_order_relaxed);
+ uptr allocsz = 64 * 1024;
+ if (allocsz < size) allocsz = size;
+ uptr mem = (uptr)MmapOrDie(allocsz, "stack depot");
+ atomic_store(&region_end, mem + allocsz, memory_order_release);
+ atomic_store(&region_pos, mem, memory_order_release);
+ }
+}
+
+extern PersistentAllocator thePersistentAllocator;
+inline void *PersistentAlloc(uptr sz) {
+ return thePersistentAllocator.alloc(sz);
+}
+
+} // namespace __sanitizer
+
+#endif // SANITIZER_PERSISTENT_ALLOCATOR_H
OpenPOWER on IntegriCloud