stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
pool.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023-2024 Amebis
4*/
5
6#pragma once
7
8#include "compat.hpp"
9#include "spinlock.hpp"
10#include "windows.h"
11#include <list>
12#include <map>
13#include <mutex>
14
15namespace stdex
16{
20 template <class T>
21 class pool
22 {
23 public:
24#ifdef _WIN32
25 using numaid_t = USHORT;
26#else
27 using numaid_t = int;
28#endif
29
30 private:
31 struct numaentry_t {
32 mutable spinlock lock;
33 std::list<T> list;
34 };
35
36 mutable std::mutex m_mutex;
37 std::map<numaid_t, numaentry_t> m_available;
38
39 private:
40 static numaid_t numa_node()
41 {
42#ifdef _WIN32
43 PROCESSOR_NUMBER Processor;
44 GetCurrentProcessorNumberEx(&Processor);
45 USHORT NodeNumber = 0;
46 return GetNumaProcessorNodeEx(&Processor, &NodeNumber) ? NodeNumber : 0;
47#else
48 return numa_node_of_cpu(sched_getcpu());
49#endif
50 }
51
52 numaentry_t& numa_entry(numaid_t numa = numa_node())
53 {
54 const std::lock_guard<std::mutex> guard(m_mutex);
55 return m_available[numa];
56 }
57
58 public:
66 T pop(_In_ numaid_t numa = numa_node())
67 {
68 auto& ne = numa_entry(numa);
69 const std::lock_guard<spinlock> guard(ne.lock);
70 if (!ne.list.empty()) {
71 auto r = std::move(ne.list.front());
72 ne.list.pop_front();
73 return r;
74 }
75 return T();
76 }
77
84 void push(_Inout_ T&& r, _In_ numaid_t numa = numa_node())
85 {
86 auto& ne = numa_entry(numa);
87 const std::lock_guard<spinlock> guard(ne.lock);
88 ne.list.push_front(std::move(r));
89 }
90
94 void clear()
95 {
96 const std::lock_guard<std::mutex> guard_m(m_mutex);
97 for (auto& ne : m_available) {
98 const std::lock_guard<spinlock> guard_l(ne.second.lock);
99 while (!ne.second.list.empty())
100 ne.second.list.pop_front();
101 }
102 }
103 };
104}
Per-NUMA pool of items.
Definition pool.hpp:22
void clear()
Removes all items from the pool.
Definition pool.hpp:94
T pop(numaid_t numa=numa_node())
Removes an item from the pool.
Definition pool.hpp:66
void push(T &&r, numaid_t numa=numa_node())
Adds an item to the pool.
Definition pool.hpp:84
Spin-lock.
Definition spinlock.hpp:22