Scheduler: torture test the thread access logic
Ensure the GroomingToken mechanism indeed creates an exclusive section protected against concurrent corruption: Use a without / with-protection test and verify the results are exact vs. grossly broken
This commit is contained in:
parent
1223772f14
commit
fa391d1267
2 changed files with 82 additions and 6 deletions
|
|
@ -28,14 +28,18 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "activity-detector.hpp"
|
||||
#include "vault/gear/scheduler-commutator.hpp"
|
||||
#include "lib/test/microbenchmark.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"///////////////////////////TODO TOD-Oh
|
||||
|
||||
//#include <utility>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
using test::Test;
|
||||
using lib::test::threadBenchmark;
|
||||
//using std::move;
|
||||
//using util::isSameObject;
|
||||
|
||||
|
|
@ -47,6 +51,14 @@ namespace test {
|
|||
// using lib::time::FrameRate;
|
||||
// using lib::time::Offset;
|
||||
using lib::time::Time;
|
||||
using std::this_thread::yield;
|
||||
using std::this_thread::sleep_for;
|
||||
using std::chrono_literals::operator ""us;
|
||||
|
||||
namespace {// Test parameters
|
||||
const size_t NUM_THREADS = 20;
|
||||
const size_t REPETITIONS = 100;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -65,6 +77,7 @@ namespace test {
|
|||
{
|
||||
demonstrateSimpleUsage();
|
||||
verify_GroomingToken();
|
||||
torture_GroomingToken();
|
||||
verify_DispatchDecision();
|
||||
verify_findWork();
|
||||
verify_postDispatch();
|
||||
|
|
@ -95,8 +108,8 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
/** @test TODO verify logic to control concurrent execution
|
||||
* @todo WIP 10/23 🔁 define ⟶ ✔ implement
|
||||
/** @test verify logic to control concurrent execution
|
||||
* @todo WIP 10/23 ✔ define ⟶ ✔ implement
|
||||
*/
|
||||
void
|
||||
verify_GroomingToken()
|
||||
|
|
@ -115,6 +128,45 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
/** @test ensure the GroomingToken mechanism indeed creates an
|
||||
* exclusive section protected against concurrent corruption.
|
||||
* @todo WIP 10/23 ✔ define ⟶ ✔ implement
|
||||
*/
|
||||
void
|
||||
torture_GroomingToken()
|
||||
{
|
||||
SchedulerCommutator sched;
|
||||
|
||||
size_t checkSum{0};
|
||||
auto pause_and_sum = [&](size_t i) -> size_t
|
||||
{
|
||||
auto oldSum = checkSum;
|
||||
sleep_for (500us);
|
||||
checkSum = oldSum + i;
|
||||
return 1;
|
||||
};
|
||||
auto protected_sum = [&](size_t i) -> size_t
|
||||
{
|
||||
while (not sched.acquireGoomingToken())
|
||||
yield();
|
||||
pause_and_sum(i);
|
||||
sched.dropGroomingToken();
|
||||
return 1;
|
||||
};
|
||||
|
||||
threadBenchmark<NUM_THREADS> (pause_and_sum, REPETITIONS);
|
||||
|
||||
size_t brokenSum = checkSum;
|
||||
checkSum = 0;
|
||||
|
||||
threadBenchmark<NUM_THREADS> (protected_sum, REPETITIONS);
|
||||
|
||||
CHECK (brokenSum < checkSum);
|
||||
CHECK (checkSum = NUM_THREADS * REPETITIONS*(REPETITIONS-1)/2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test TODO verify the decision logic where and when
|
||||
* to perform the dispatch of an Scheduler Activity chain.
|
||||
* @todo WIP 10/23 🔁 define ⟶ implement
|
||||
|
|
|
|||
|
|
@ -86130,13 +86130,37 @@ Date:   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="#eef0c5" COLOR="#990000" CREATED="1697560505486" ID="ID_1321080717" LINK="#ID_409935766" MODIFIED="1697567781570" TEXT="verify_GroomingToken">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1697560505486" ID="ID_1321080717" LINK="#ID_409935766" MODIFIED="1697571165841" TEXT="verify_GroomingToken">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<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üfen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1697567807797" ID="ID_727144222" MODIFIED="1697571095208" TEXT="Multithread-Exclusion prüfen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1697570731407" ID="ID_1686773037" MODIFIED="1697570736338" TEXT="mit / ohne Test"/>
|
||||
<node CREATED="1697570737358" ID="ID_1684442461" MODIFIED="1697571093390" TEXT="microbenchmark verwenden">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1697570844041" ID="ID_744923834" MODIFIED="1697570856555" TEXT="100 Wiederholungen in 20 Threads"/>
|
||||
<node CREATED="1697570748133" ID="ID_1723527988" MODIFIED="1697571093396" TEXT="Ergebnisse sind sehr deutlich">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
ohne Schutz braucht die Operation ∅ 600µs (bei 500µs Schlafpause) und die Checksumme ist viel zu klein (~6000 statt wie erwartet 99000)
|
||||
</li>
|
||||
<li>
|
||||
mit Schutz braucht die Operation im Schnitt 10ms und die Summe 0...N-1 stimmt exakt
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="list"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697560511607" ID="ID_764686457" MODIFIED="1697560620825" TEXT="verify_DispatchDecision">
|
||||
|
|
|
|||
Loading…
Reference in a new issue