FreeTensor
Loading...
Searching...
No Matches
allocator.h
Go to the documentation of this file.
1#ifndef FREE_TENSOR_ALLOCATOR_H
2#define FREE_TENSOR_ALLOCATOR_H
3
4#include <atomic>
5#include <cstdint>
6#include <cstdlib>
7#include <vector>
8
9namespace freetensor {
10
11constexpr int SMALL_ITEM_SIZE = 64;
12constexpr int SMALL_ITEM_PER_BLOCK = 16384 / SMALL_ITEM_SIZE;
13
14union SmallItem {
17};
18
21
22 private:
23 SmallItemBlock() = default;
24 ~SmallItemBlock() = default;
25
26 public:
27 bool full() const;
28 [[nodiscard]] SmallItem *allocate();
29 void deallocate(SmallItem *item);
30
31 static SmallItemBlock *newBlk();
32 static void delBlk(SmallItemBlock *blk);
33};
34static_assert(sizeof(SmallItemBlock) == SMALL_ITEM_SIZE * SMALL_ITEM_PER_BLOCK);
35
37 size_t curBlk;
38 std::vector<SmallItemBlock *> blocks_;
39 std::atomic_flag spinLock_ = ATOMIC_FLAG_INIT;
40
41 // We must define instance_ as a static pointer of an dynamic object,
42 // instead of a static object, and the dynamic object shall never be free'd.
43 // Otherwise, some static variables that use the allocator may be free'd
44 // after the allocator
45 static thread_local SmallItemAllocator *instance_;
46
47 private:
48 void lock();
49 void unlock();
50
51 public:
54
55 [[nodiscard]] void *allocate();
56 void deallocate(void *p);
57
59 if (instance_ == nullptr) {
60 instance_ = new SmallItemAllocator();
61 }
62 return instance_;
63 }
64};
65
66template <class T> class Allocator {
67 SmallItemAllocator *smallItemAllocator_;
68
69 public:
70 typedef T value_type;
71 typedef std::true_type is_always_equal;
72
73 Allocator() : smallItemAllocator_(SmallItemAllocator::instance()) {}
74
75 template <class U> Allocator(const Allocator<U> &other) : Allocator() {}
76 template <class U> Allocator(Allocator<U> &&other) : Allocator() {}
77
78 [[nodiscard]] T *allocate(size_t n) {
79 if (n * sizeof(T) > SMALL_ITEM_SIZE) {
80 return (T *)malloc(n * sizeof(T));
81 } else {
82 return (T *)smallItemAllocator_->allocate();
83 }
84 }
85
86 void deallocate(T *p, size_t n) {
87 if (n * sizeof(T) > SMALL_ITEM_SIZE) {
88 free(p);
89 } else {
90 smallItemAllocator_->deallocate(p);
91 }
92 }
93
94 template <class... Args> void construct(T *p, Args &&...args) {
95 ::new ((void *)p) T(std::forward<Args>(args)...);
96 }
97};
98
99template <class T>
101 return true;
102}
103
104} // namespace freetensor
105
106#endif // FREE_TENSOR_ALLOCATOR_H
Definition: allocator.h:66
Allocator(Allocator< U > &&other)
Definition: allocator.h:76
T * allocate(size_t n)
Definition: allocator.h:78
T value_type
Definition: allocator.h:70
Allocator()
Definition: allocator.h:73
Allocator(const Allocator< U > &other)
Definition: allocator.h:75
void construct(T *p, Args &&...args)
Definition: allocator.h:94
void deallocate(T *p, size_t n)
Definition: allocator.h:86
std::true_type is_always_equal
Definition: allocator.h:71
Definition: allocator.h:36
void * allocate()
Definition: allocator.cc:53
SmallItemAllocator()
Definition: allocator.cc:34
static SmallItemAllocator * instance()
Definition: allocator.h:58
~SmallItemAllocator()
Definition: allocator.cc:37
void deallocate(void *p)
Definition: allocator.cc:71
Definition: allocator.h:19
static void delBlk(SmallItemBlock *blk)
Definition: allocator.cc:30
static SmallItemBlock * newBlk()
Definition: allocator.cc:20
SmallItem * allocate()
Definition: allocator.cc:9
void deallocate(SmallItem *item)
Definition: allocator.cc:15
bool full() const
Definition: allocator.cc:7
int n
Definition: metadata.cc:15
Definition: allocator.h:9
constexpr int SMALL_ITEM_PER_BLOCK
Definition: allocator.h:12
auto && lhs
Definition: const_fold.cc:70
constexpr int SMALL_ITEM_SIZE
Definition: allocator.h:11
bool operator==(const Allocator< T > &lhs, const Allocator< T > &rhs)
Definition: allocator.h:100
auto auto && rhs
Definition: const_fold.cc:70
Definition: allocator.h:14
uint8_t data_[SMALL_ITEM_SIZE]
Definition: allocator.h:16
SmallItem * next_
Definition: allocator.h:15