From fa391d1267f707abe8d770d383fd3eebe56e490d Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 17 Oct 2023 21:35:37 +0200 Subject: [PATCH] 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 --- .../vault/gear/scheduler-commutator-test.cpp | 56 ++++++++++++++++++- wiki/thinkPad.ichthyo.mm | 32 +++++++++-- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/tests/vault/gear/scheduler-commutator-test.cpp b/tests/vault/gear/scheduler-commutator-test.cpp index cc8b98f0c..c2adf62c4 100644 --- a/tests/vault/gear/scheduler-commutator-test.cpp +++ b/tests/vault/gear/scheduler-commutator-test.cpp @@ -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 #include +#include 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 (pause_and_sum, REPETITIONS); + + size_t brokenSum = checkSum; + checkSum = 0; + + threadBenchmark (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 diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index ce3eef930..59055f8cb 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -86130,13 +86130,37 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + - - + + + + + + + + + + + + + +
    +
  • + ohne Schutz braucht die Operation ∅ 600µs (bei 500µs Schlafpause) und die Checksumme ist viel zu klein (~6000 statt wie erwartet 99000) +
  • +
  • + mit Schutz braucht die Operation im Schnitt 10ms und die Summe 0...N-1 stimmt exakt +
  • +
+ + +
+ +