Scheduler: implement thread access logic

T thread holding the »Grooming Token" is permitted to
manipulate scheduler internals and thus also to define new
activities; this logic is implemented as an Atomic lock,
based on the current thread's ID.
This commit is contained in:
Fischlurch 2023-10-17 20:34:54 +02:00
parent 862933e809
commit 1223772f14
3 changed files with 106 additions and 18 deletions

View file

@ -47,12 +47,18 @@
//#include "lib/util.hpp"
//#include <string>
#include <thread>
#include <atomic>
namespace vault{
namespace gear {
using lib::time::Time;
using std::atomic;
using std::memory_order::memory_order_relaxed;
using std::memory_order::memory_order_acquire;
using std::memory_order::memory_order_release;
// using util::isnil;
// using std::string;
@ -66,12 +72,60 @@ namespace gear {
class SchedulerCommutator
: util::NonCopyable
{
using ThreadID = std::thread::id;
atomic<ThreadID> groomingToken_{};
public:
// explicit
SchedulerCommutator()
{ }
/**
* acquire the right to perform internal state transitions.
* @return `true` if this attempt succeeded
* @note only one thread at a time can acquire the GoomingToken successfully.
* @remark only if _testing and branching_ on the return value, this also constitutes
* also sync barrier; _in this case you can be sure_ to see the real values
* of any scheduler internals and are free to manipulate.
*/
bool
acquireGoomingToken() noexcept
{
ThreadID expect_noThread; // expect no one else to be in...
ThreadID myself = std::this_thread::get_id();
return groomingToken_.compare_exchange_strong (expect_noThread, myself
,memory_order_acquire // success also constitutes an acquire barrier
,memory_order_relaxed // failure has no synchronisation ramifications
);
}
/**
* relinquish the right for internal transitions.
* @remark any changes done to scheduler internals prior to this call will be
* _sequenced-before_ anything another thread does later, _bot only_
* if the other thread first successfully acquires the GroomingToken.
*/
void
dropGroomingToken() noexcept
{ // expect that this thread actually holds the Grooming-Token
REQUIRE (groomingToken_.load(memory_order_relaxed) == std::this_thread::get_id());
const ThreadID noThreadHoldsIt;
groomingToken_.store (noThreadHoldsIt, memory_order_release);
}
/**
* check if the indicated thread currently holds
* the right to conduct internal state transitions.
*/
bool
holdsGroomingToken (ThreadID id) noexcept
{
return id == groomingToken_.load (memory_order_relaxed);
}
Activity*
findWork (SchedulerInvocation& layer1)
{

View file

@ -33,6 +33,7 @@
//#include "lib/util.hpp"
//#include <utility>
#include <thread>
using test::Test;
//using std::move;
@ -88,18 +89,28 @@ namespace test {
// use the ActivityDetector for test instrumentation...
ActivityDetector detector;
sched.postDispatch (sched.findWork(queues), detector.executionCtx);
// sched.postDispatch (sched.findWork(queues), detector.executionCtx); ///////////////////////OOO findWork umschreiben
cout << detector.showLog()<<endl; // HINT: use this for investigation...
}
/** @test TODO verify logic to control concurrent execution
* @todo WIP 10/23 🔁 define implement
* @todo WIP 10/23 🔁 define implement
*/
void
verify_GroomingToken()
{
SchedulerCommutator sched;
auto myself = std::this_thread::get_id();
CHECK (not sched.holdsGroomingToken (myself));
CHECK (sched.acquireGoomingToken());
CHECK ( sched.holdsGroomingToken (myself));
sched.dropGroomingToken();
CHECK (not sched.holdsGroomingToken (myself));
}

View file

@ -85010,8 +85010,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697553250983" ID="ID_438556046" MODIFIED="1697553470423" TEXT="doWork &#x27fc; findWork">
<linktarget COLOR="#718daf" DESTINATION="ID_438556046" ENDARROW="Default" ENDINCLINATION="-261;714;" ID="Arrow_ID_1821254034" SOURCE="ID_1076701414" STARTARROW="None" STARTINCLINATION="372;24;"/>
<linktarget COLOR="#7b8795" DESTINATION="ID_438556046" ENDARROW="Default" ENDINCLINATION="28;-22;" ID="Arrow_ID_520978128" SOURCE="ID_1600142035" STARTARROW="None" STARTINCLINATION="-463;26;"/>
<linktarget COLOR="#718daf" DESTINATION="ID_438556046" ENDARROW="Default" ENDINCLINATION="-261;714;" ID="Arrow_ID_1821254034" SOURCE="ID_1076701414" STARTARROW="None" STARTINCLINATION="372;24;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1697560260874" ID="ID_1507199243" MODIFIED="1697560276691" TEXT="versucht das GroomingToken zu erlangen"/>
<node CREATED="1697560224719" ID="ID_1707640697" MODIFIED="1697560260107" TEXT="macht die Queue-Updates"/>
@ -85026,8 +85026,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
wir sind hier in einer performance-kritischen Zone; insofern kein std::optional&lt;Activity&amp;&gt;
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697553556862" ID="ID_239855477" MODIFIED="1697553563674" TEXT="PostDispatch">
@ -85082,20 +85081,38 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<linktarget COLOR="#6d677a" DESTINATION="ID_1453351337" ENDARROW="Default" ENDINCLINATION="7;-29;" ID="Arrow_ID_1868115325" SOURCE="ID_937487663" STARTARROW="None" STARTINCLINATION="-51;3;"/>
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697559873907" ID="ID_409935766" MODIFIED="1697559945129" TEXT="acquireGoomingToken">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1697560125437" ID="ID_129201087" MODIFIED="1697560132875" TEXT="implementiert als Compare-and-Swap"/>
<node CREATED="1697560134935" ID="ID_1881068122" MODIFIED="1697560151665" TEXT="R&#xfc;ckgabewert bool &#x27fc; Erfolg"/>
<node COLOR="#338800" CREATED="1697559873907" ID="ID_409935766" MODIFIED="1697567713362" TEXT="acquireGoomingToken">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1697560125437" ID="ID_129201087" MODIFIED="1697567708667" TEXT="implementiert als Compare-and-Swap">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697559880222" ID="ID_1458427038" MODIFIED="1697559945129" TEXT="dropGroomingToken">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1697560157372" ID="ID_1167908140" MODIFIED="1697560172871" TEXT="Konsiistenzpr&#xfc;fung nur als Assertion"/>
<node CREATED="1697560173410" ID="ID_1045304813" MODIFIED="1697560193547" TEXT="Thread-ID 0 in das Token schreiben"/>
<node COLOR="#338800" CREATED="1697560134935" ID="ID_1881068122" MODIFIED="1697567711227" TEXT="R&#xfc;ckgabewert bool &#x27fc; Erfolg">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1697567715658" ID="ID_1830973768" MODIFIED="1697567728848" TEXT="Entscheidung zur Memory-order">
<icon BUILTIN="yes"/>
<node CREATED="1697567729992" ID="ID_322976038" MODIFIED="1697567738475" TEXT="acquire = memory_order_acquire"/>
<node CREATED="1697567739422" ID="ID_481777766" MODIFIED="1697567745105" TEXT="drop = memory_order_release"/>
<node CREATED="1697567746057" ID="ID_193744284" MODIFIED="1697567749561" TEXT="alles andere: relaxed"/>
</node>
</node>
<node COLOR="#338800" CREATED="1697559880222" ID="ID_1458427038" MODIFIED="1697567772880" TEXT="dropGroomingToken">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1697560157372" ID="ID_1167908140" MODIFIED="1697567753440" TEXT="Konsiistenzpr&#xfc;fung nur als Assertion">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1697560173410" ID="ID_1045304813" MODIFIED="1697567764180" TEXT="Thread-ID &lt;leer&gt; in das Token schreiben">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1697559931219" ID="ID_199319740" MODIFIED="1697567772039" TEXT="holdsGroomingToken">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1697560065912" ID="ID_1054899813" MODIFIED="1697567766331" TEXT="zur besseren Lesbarkeit: Thread-ID als Argument">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1697560079607" ID="ID_692116285" MODIFIED="1697567770557" TEXT="ist dann eine relativ leichtgewichtige Operation">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697559931219" ID="ID_199319740" MODIFIED="1697560003977" TEXT="holdsGroomingToken">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1697560065912" ID="ID_1054899813" MODIFIED="1697560078523" TEXT="zur besseren Lesbarkeit: Thread-ID als Argument"/>
<node CREATED="1697560079607" ID="ID_692116285" MODIFIED="1697560102616" TEXT="ist dann eine relativ leichtgewichtige Operation"/>
</node>
</node>
<node CREATED="1687788623248" ID="ID_1335631068" MODIFIED="1687788627335" TEXT="Ausf&#xfc;hrungs-Struktur">
@ -86113,9 +86130,15 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1697560628310" ID="ID_670606112" MODIFIED="1697562328081" TEXT="demonstrateSimpleUsage">
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697560505486" ID="ID_1321080717" MODIFIED="1697560620826" TEXT="verify_GroomingToken">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1697560505486" ID="ID_1321080717" LINK="#ID_409935766" MODIFIED="1697567781570" TEXT="verify_GroomingToken">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1697567790616" ID="ID_1691764279" MODIFIED="1697567807166" TEXT="API-Reaktion direkt im aktuellen Thread verifizieren">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697567807797" ID="ID_727144222" MODIFIED="1697567830467" TEXT="Multithread-Exclusion pr&#xfc;fen">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697560511607" ID="ID_764686457" MODIFIED="1697560620825" TEXT="verify_DispatchDecision">
<icon BUILTIN="flag-yellow"/>
</node>