Skip to content
Snippets Groups Projects
Commit 64ba4c05 authored by Florian Schmaus's avatar Florian Schmaus
Browse files

Merge branch 'laws-opti' into 'master'

[LAWS/Fiber] Introduce the concept of Multi-Fiber

See merge request !195
parents 058ba7f3 9a255dd5
No related branches found
No related tags found
1 merge request!195[LAWS/Fiber] Introduce the concept of Multi-Fiber
Pipeline #62266 passed
......@@ -30,7 +30,12 @@ class Dispatcher : public Logger<LogSubsystem::DISP> {
fiber->run();
}
static inline auto isRunnable(Fiber* fiber) -> bool { return fiber->setRunnableFalse(); }
static inline auto isRunnable(Fiber* fiber) -> bool {
if (fiber->isMultiFiber()) {
return fiber->setRunnableFalse();
}
return true;
}
static inline auto getAffinityBuffer(Fiber* fiber) -> workeraffinity_t* {
return fiber->getAffinityBuffer();
......
......@@ -36,6 +36,12 @@ class ALIGN_TO_CACHE_LINE Fiber : public Logger<LogSubsystem::F> {
const fiber_fun_t function;
void* const arg;
/**
* Denotes if this is a multi Fiber, i.e. a Fiber that is placed in
* multiple ready-lists, instead of just one.
*/
bool isMulti = false;
std::atomic<bool> runnable = {true};
ALIGN_TO_CACHE_LINE std::atomic_uint referenceCounter = {1};
......@@ -85,14 +91,23 @@ class ALIGN_TO_CACHE_LINE Fiber : public Logger<LogSubsystem::F> {
return runnable.exchange(false);
}
inline auto doAtomicIncrRefCount() -> unsigned int {
inline void doAtomicIncrRefCount() {
assert(referenceCounter < UINT_MAX);
return ++referenceCounter;
isMulti = true;
// Note: Although the first impulse is to prevent the re-ordering
// of the isMulti store after the reference counter modification,
// this *should* not be necessary. The sychronization point where
// this ordering is guranteed is, when the fiber is put in a
// concurrent queue. There the queue must gurantee that all
// previous stores are visible at the time the fiber appears in
// the queue to other threads.
referenceCounter.fetch_add(1, std::memory_order_relaxed);
}
inline auto doAtomicDecrRefCount() -> unsigned int {
assert(referenceCounter > 0);
return --referenceCounter;
auto previous = referenceCounter.fetch_sub(1, std::memory_order_acq_rel);
return previous - 1;
}
template <LogSubsystem>
......@@ -114,6 +129,8 @@ class ALIGN_TO_CACHE_LINE Fiber : public Logger<LogSubsystem::F> {
[[nodiscard]] auto isRunnable() const -> bool { return runnable; }
[[nodiscard]] auto isMultiFiber() const -> bool { return isMulti; }
friend auto operator<<(std::ostream& strm, const Fiber& fiber) -> std::ostream&;
static inline auto from(fiber_fun_t function, void* arg) -> Fiber* {
......
......@@ -4,6 +4,7 @@
#include "Common.hpp" // for DIE_MSG
#include "Emper.hpp"
#include "Fiber.hpp"
#include "LawsStrategy.hpp" // for LawsStrategy, LawsStrategy::FiberSource
#include "NextFiberResult.hpp"
#include "Runtime.hpp"
......@@ -12,8 +13,10 @@
void LawsDispatcher::recycle(Fiber* fiber) {
// If the ref count has not reached zero yet, do not recycle the
// fiber.
if (decreaseRefCount(fiber)) return;
// fiber. But only if the fiber is a multi fiber, i.e. was placed
// in multiple queues in the first place, and hence needed to be
// refcounted.
if (fiber->isMultiFiber() && decreaseRefCount(fiber)) return;
Dispatcher::recycle(fiber);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment