File indexing completed on 2026-05-10 08:44:34
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_SUPPORT_THREADSAFEALLOCATOR_H
0010 #define LLVM_SUPPORT_THREADSAFEALLOCATOR_H
0011
0012 #include "llvm/ADT/STLExtras.h"
0013 #include "llvm/Support/Allocator.h"
0014 #include <atomic>
0015
0016 namespace llvm {
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 template <class AllocatorType> class ThreadSafeAllocator {
0027 struct LockGuard {
0028 LockGuard(std::atomic_flag &Flag) : Flag(Flag) {
0029 if (LLVM_UNLIKELY(Flag.test_and_set(std::memory_order_acquire)))
0030 while (Flag.test_and_set(std::memory_order_acquire)) {
0031 }
0032 }
0033 ~LockGuard() { Flag.clear(std::memory_order_release); }
0034 std::atomic_flag &Flag;
0035 };
0036
0037 public:
0038 auto Allocate(size_t N) {
0039 return applyLocked([N](AllocatorType &Alloc) { return Alloc.Allocate(N); });
0040 }
0041
0042 auto Allocate(size_t Size, size_t Align) {
0043 return applyLocked([Size, Align](AllocatorType &Alloc) {
0044 return Alloc.Allocate(Size, Align);
0045 });
0046 }
0047
0048 template <typename FnT,
0049 typename T = typename llvm::function_traits<FnT>::result_t>
0050 T applyLocked(FnT Fn) {
0051 LockGuard Lock(Flag);
0052 return Fn(Alloc);
0053 }
0054
0055 private:
0056 AllocatorType Alloc;
0057 std::atomic_flag Flag = ATOMIC_FLAG_INIT;
0058 };
0059
0060 }
0061
0062 #endif