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#ifdef _WIN32
11#include "windows.h"
12#endif
13#include <list>
14#include <map>
15#include <mutex>
16
17 namespace stdex
18{
22 template <class T>
23 class pool
24 {
25 public:
26#ifdef _WIN32
27 using numaid_t = USHORT;
28#else
29 using numaid_t = int;
30#endif
31
32 private:
33 struct numaentry_t {
34 mutable spinlock lock;
35 std::list<T> list;
36 };
37
38 mutable std::mutex m_mutex;
39 std::map<numaid_t, numaentry_t> m_available;
40
41 private:
42 static numaid_t numa_node()
43 {
44#if defined(_WIN32)
45 PROCESSOR_NUMBER Processor;
46 GetCurrentProcessorNumberEx(&Processor);
47 USHORT NodeNumber = 0;
48 return GetNumaProcessorNodeEx(&Processor, &NodeNumber) ? NodeNumber : 0;
49#elif defined(__APPLE__)
50 return 0;
51#else
52 return numa_node_of_cpu(sched_getcpu());
53#endif
54 }
55
56 numaentry_t& numa_entry(numaid_t numa = numa_node())
57 {
58 const std::lock_guard<std::mutex> guard(m_mutex);
59 return m_available[numa];
60 }
61
62 public:
70 T pop(_In_ numaid_t numa = numa_node())
71 {
72 auto& ne = numa_entry(numa);
73 const std::lock_guard<spinlock> guard(ne.lock);
74 if (!ne.list.empty()) {
75 auto r = std::move(ne.list.front());
76 ne.list.pop_front();
77 return r;
78 }
79 return T();
80 }
81
88 void push(_Inout_ T&& r, _In_ numaid_t numa = numa_node())
89 {
90 auto& ne = numa_entry(numa);
91 const std::lock_guard<spinlock> guard(ne.lock);
92 ne.list.push_front(std::move(r));
93 }
94
98 void clear()
99 {
100 const std::lock_guard<std::mutex> guard_m(m_mutex);
101 for (auto& ne : m_available) {
102 const std::lock_guard<spinlock> guard_l(ne.second.lock);
103 while (!ne.second.list.empty())
104 ne.second.list.pop_front();
105 }
106 }
107 };
108}
stdex::pool
Per-NUMA pool of items.
Definition pool.hpp:24
stdex::pool::clear
void clear()
Removes all items from the pool.
Definition pool.hpp:98
stdex::pool::pop
T pop(numaid_t numa=numa_node())
Removes an item from the pool.
Definition pool.hpp:70
stdex::pool::push
void push(T &&r, numaid_t numa=numa_node())
Adds an item to the pool.
Definition pool.hpp:88
stdex::spinlock
Spin-lock.
Definition spinlock.hpp:22