YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
scheduler.cpp
Go to the documentation of this file.
1#include <fault/util.hpp>
2
5
6#include <cstdio>
7
8namespace yaclib::fault {
9
10static Scheduler* sCurrentScheduler = nullptr;
11static thread_local detail::fiber::FiberBase* sCurrent = nullptr;
12static std::uint32_t sTickLength = 10;
13
14detail::fiber::FiberBase* Scheduler::GetNext() {
15 YACLIB_DEBUG(_queue.Empty(), "Queue can't be empty");
16 auto* next = PollRandomElementFromList(_queue);
17 return static_cast<detail::fiber::FiberBase*>(static_cast<detail::fiber::BiNodeScheduler*>(next));
18}
19
21 return _running;
22}
23
25 auto* fiber = sCurrent;
26 YACLIB_ASSERT(fiber != nullptr);
27 fiber->Suspend();
28}
29
33
37
40 _queue.PushBack(static_cast<detail::fiber::BiNodeScheduler*>(fiber));
41 if (!_running) {
42 _running = true;
43 RunLoop();
44 _running = false;
45 }
46}
47
51
53 return sCurrent != nullptr ? sCurrent->GetId() : detail::fiber::FiberBase::Id{static_cast<std::uint64_t>(-1)};
54}
55
56void Scheduler::TickTime() noexcept {
57 _time += sTickLength;
58}
59
60void Scheduler::AdvanceTime() noexcept {
61 if (_sleep_list.begin()->first >= _time) {
62 auto min_sleep_time = _sleep_list.begin()->first - _time;
63 _time += min_sleep_time;
64 }
65}
66
68 return _time;
69}
70
71void Scheduler::WakeUpNeeded() noexcept {
72 auto iter_to_remove = _sleep_list.end();
73 for (auto it = _sleep_list.begin(); it != _sleep_list.end(); it++) {
74 if (it->first > _time) {
76 break;
77 }
78 _queue.PushAll(std::move(it->second));
79 }
80 if (iter_to_remove != _sleep_list.begin()) {
81 _sleep_list.erase(_sleep_list.begin(), iter_to_remove);
82 }
83}
84
85void Scheduler::RunLoop() {
86 while (!_queue.Empty() || !_sleep_list.empty()) {
87 if (_queue.Empty()) {
88 AdvanceTime();
89 }
90 WakeUpNeeded();
91 auto* next = GetNext();
92 sCurrent = next;
93 TickTime();
94 next->Resume();
95 if (next->GetState() == detail::fiber::Completed && !next->IsThreadAlive()) {
96 delete next;
97 }
98 }
99 sCurrent = nullptr;
100}
101
103 if (sCurrent == nullptr) {
104 return;
105 }
106 auto* fiber = sCurrent;
107 GetScheduler()->_queue.PushBack(static_cast<detail::fiber::BiNodeScheduler*>(fiber));
108 fiber->Suspend();
109}
110
111void Scheduler::SetTickLength(std::uint32_t tick) noexcept {
113}
114
115void Scheduler::Sleep(std::uint64_t ns) {
116 if (ns <= GetTimeNs()) {
117 return;
118 }
119 detail::fiber::BiList& sleep_list = _sleep_list[ns];
120 auto* fiber = sCurrent;
121 sleep_list.PushBack(static_cast<detail::fiber::BiNodeScheduler*>(fiber));
122 Suspend();
123}
124
125void Scheduler::SleepPreemptive(std::uint64_t ns) {
127 Sleep(ns);
128 // <= because wakeup called before time adjustment
129 if (_time <= ns) {
130 auto it = _sleep_list.find(ns);
131 YACLIB_DEBUG(it == _sleep_list.end(), "sleep_list for time that is not passed yet isn't found");
132 if (it->second.Empty()) {
133 _sleep_list.erase(ns);
134 }
135 }
136}
137
138} // namespace yaclib::fault
139namespace yaclib::detail::fiber {
140
141static std::uint32_t sRandomListPick = 10;
142
143void SetRandomListPick(std::uint32_t k) noexcept {
145}
146
149 auto reversed = false;
150 if (rand_pos >= sRandomListPick) {
151 reversed = true;
153 }
154 auto* next = list.GetElement(rand_pos, reversed);
155 next->Erase();
156 return next;
157}
158
159} // namespace yaclib::detail::fiber
void SetState(FiberState state) noexcept
void Schedule(detail::fiber::FiberBase *fiber)
Definition scheduler.cpp:38
static void SetTickLength(std::uint32_t tick) noexcept
static detail::fiber::FiberBase::Id GetId()
Definition scheduler.cpp:52
static void RescheduleCurrent()
std::uint64_t GetTimeNs() const noexcept
Definition scheduler.cpp:67
void SleepPreemptive(std::uint64_t ns)
static void Set(Scheduler *scheduler) noexcept
Definition scheduler.cpp:34
static Scheduler * GetScheduler() noexcept
Definition scheduler.cpp:30
static detail::fiber::FiberBase * Current() noexcept
Definition scheduler.cpp:48
void Sleep(std::uint64_t ns)
bool IsRunning() const noexcept
Definition scheduler.cpp:20
#define YACLIB_DEBUG(cond, message)
Definition log.hpp:84
#define YACLIB_ASSERT(cond)
Definition log.hpp:85
Node * PollRandomElementFromList(BiList &list)
static std::uint32_t sRandomListPick
void SetRandomListPick(std::uint32_t k) noexcept
std::uint64_t GetRandNumber(std::uint64_t max)
Definition util.cpp:22
static std::uint32_t sTickLength
Definition scheduler.cpp:12
static Scheduler * sCurrentScheduler
Definition scheduler.cpp:10
static thread_local detail::fiber::FiberBase * sCurrent
Definition scheduler.cpp:11
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25
std::uint32_t GetFaultSleepTime() noexcept
Definition config.cpp:23