YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
shared_core.hpp
Go to the documentation of this file.
1#pragma once
2
7#include <yaclib/fwd.hpp>
8#include <yaclib/util/ref.hpp>
9
10#include <atomic>
11
12namespace yaclib {
13namespace detail {
14
15template <typename V, typename E>
16class SharedCore : public IRef {
18
19 public:
21
23 ResultCoreType* core = p.GetCore().Get();
24 ResultCoreType* next = _head.load(std::memory_order_acquire);
25 do {
26 if (reinterpret_cast<std::uintptr_t>(next) == kSet) {
27 std::move(p).Set(_result);
28 break;
29 }
30 core->next = next;
31 } while (!_head.compare_exchange_weak(next, core, std::memory_order_release, std::memory_order_acquire));
32 p.GetCore().Release();
33 }
34
35 template <typename... Args>
36 void Set(Args&&... args) {
37 new (&_result) Result<V, E>{std::forward<Args>(args)...};
38
39 auto head = _head.exchange(reinterpret_cast<ResultCoreType*>(kSet), std::memory_order_acq_rel);
40 YACLIB_ASSERT(reinterpret_cast<std::uintptr_t>(head) != kSet);
41
42 while (head) {
43 auto next = head->next;
45 head = static_cast<ResultCoreType*>(next);
46 }
47 }
48
50 YACLIB_ASSERT(reinterpret_cast<std::uintptr_t>(_head.load(std::memory_order_relaxed)) == kSet);
51 _result.~Result<V, E>();
52 }
53
54 private:
55 static constexpr auto kSet = std::numeric_limits<std::uintptr_t>::max();
56
57 yaclib_std::atomic<ResultCoreType*> _head = nullptr;
58 union {
60 };
61};
62
63template <typename V, typename E>
65
66} // namespace detail
67} // namespace yaclib
Reference counting interface.
Definition ref.hpp:8
A intrusive pointer to objects with an embedded reference count.
Encapsulated return value from caller.
Definition result.hpp:90
Result< V, E > & Get() noexcept
void Set(Args &&... args)
void Attach(Promise< V, E > &&p)
#define YACLIB_ASSERT(cond)
Definition log.hpp:85
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25