bux API Reference 1.9.0
Static library of whatever are seen required in general purpose but not directly supported from Modern C++. Or whatever reusable originated from my side projects.
Loading...
Searching...
No Matches
AtomiX.h
Go to the documentation of this file.
1#pragma once
2
3#include <atomic> // std::atomic_flag
4#include <concepts> // std::constructible_from<>, std::invocable<>
5#include <map> // std::map<>
6#include <thread> // std::this_thread::yield()
7
8namespace bux {
9
10//
11// Types
12//
14{
15public:
16
17 // Ctor/Dtor
18 C_SpinLock(std::atomic_flag &lock_);
20 void operator=(const C_SpinLock&) = delete;
21 void unlock();
22
23private:
24
25 // Data
26 std::atomic_flag *m_lock;
27};
28
29template<typename T_Key, typename T_Value, bool YIELD_BEFORE_RETRY = false>
31{
32public:
33
34 // Nonvirtuals
35 template<class T_KeyIn, class F>
36 const T_Value &operator()(T_KeyIn key, F set_value) requires
37 std::constructible_from<T_Key,T_KeyIn> && std::invocable<F,T_Value&>
38 {
39 bux::C_SpinLock lockMap{m_lock};
40 const auto ins_ret = m_map.try_emplace(key);
41 auto &ret = ins_ret.first->second;
42 lockMap.unlock();
43 if (ins_ret.second)
44 {
45 set_value(ret.m_value);
46 ret.m_ready = true;
47 }
48 else while (!ret.m_ready)
49 {
50 if constexpr (YIELD_BEFORE_RETRY)
51 std::this_thread::yield();
52 }
53 return ret.m_value;
54 }
55 auto size() const
56 {
57 bux::C_SpinLock _{m_lock};
58 return m_map.size();
59 }
60
61private:
62
63 // Types
64 struct C_Mapped
65 {
66 T_Value m_value;
67 std::atomic<bool> m_ready{false}; // oneway: false -> true
68 };
69
70 // Data
71 std::map<T_Key, C_Mapped> m_map;
72 std::atomic_flag mutable m_lock = ATOMIC_FLAG_INIT;
73};
74
75} // namespace bux
const T_Value & operator()(T_KeyIn key, F set_value)
Definition AtomiX.h:36
auto size() const
Definition AtomiX.h:55
C_SpinLock(std::atomic_flag &lock_)
Definition AtomiX.cpp:8
void operator=(const C_SpinLock &)=delete
void unlock()
Definition AtomiX.cpp:20
THE common namespace of bux library.
Definition AtomiX.cpp:3