Skip to content

Commit ea698ab

Browse files
committed
Add ThreadSafePool
1 parent c4014c5 commit ea698ab

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

util/thread_safe_pool.hh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#pragma once
2+
#include <array>
3+
#include <atomic>
4+
#include <cstddef>
5+
#include <optional>
6+
7+
namespace cpputil
8+
{
9+
10+
template<typename T, size_t MaxEntries>
11+
class ThreadSafePool {
12+
private:
13+
std::array<T, MaxEntries> data;
14+
std::array<std::atomic<bool>, MaxEntries> used_flags;
15+
16+
public:
17+
ThreadSafePool() = default;
18+
19+
// Returns index of first available entry
20+
// Returns nullopt if none available
21+
std::optional<size_t> create() {
22+
for (size_t i = 0; auto &used : used_flags) {
23+
bool expected = false;
24+
if (used.compare_exchange_strong(expected, true)) {
25+
return i;
26+
}
27+
i++;
28+
}
29+
return std::nullopt;
30+
}
31+
32+
// Returns whether item was actually destroyed
33+
bool destroy(size_t idx) {
34+
if (idx < used_flags.size()) {
35+
bool expected = true;
36+
if (used_flags[idx].compare_exchange_strong(expected, false)) {
37+
return true;
38+
}
39+
}
40+
return false;
41+
}
42+
43+
void clear() {
44+
for (size_t i = 0; i < MaxEntries; i++) {
45+
data[i] = T{};
46+
used_flags[i].store(false, std::memory_order_acquire);
47+
}
48+
}
49+
50+
T &operator[](size_t idx) {
51+
return data[idx];
52+
}
53+
54+
T &operator[](size_t idx) const {
55+
return data[idx];
56+
}
57+
};
58+
59+
} // namespace cpputil

0 commit comments

Comments
 (0)