From 46fc900980bd0e550dce6240bd87df8bc3064eac Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 7 Aug 2017 01:00:36 +0200 Subject: [PATCH] UI-Dispatch: get the multithreded test to work (#1098) the (trivial) implementation turned out to be correct as written, but it was (again) damn challenging to get the mulithreaded chaotic test fixture and especially the lambda captures to work correct. --- tests/25fundamental.tests | 9 +++- tests/basics/call-queue-test.cpp | 71 ++++++++++++++++++-------------- wiki/thinkPad.ichthyo.mm | 16 +++---- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/tests/25fundamental.tests b/tests/25fundamental.tests index dd1af2eda..c244e1ca0 100644 --- a/tests/25fundamental.tests +++ b/tests/25fundamental.tests @@ -51,7 +51,12 @@ return: 0 END -TEST "LifeCycle_test" LifeCycle_test <; - struct Worker : ThreadJoinable + , Sync<> { - uint64_t localSum = 0; + uint64_t producerSum = 0; + uint64_t consumerSum = 0; - Worker(uint cnt, Step workStep) + void + countConsumerCall (uint increment) + { + Lock sync(this); // NOTE: will be invoked from some random other thread + consumerSum += increment; + } + + Worker(CallQueue& queue) : ThreadJoinable{"CallQueue_test: concurrent dispatch" , [&]() { + uint cnt = rand() % MAX_RAND_STEPS; + uint delay = rand() % MAX_RAND_DELAY; + for (uint i=0; i; + /** + * @test torture the CallQueue by massively multithreaded dispatch + * - start #NUM_OF_THREADS (e.g. 50) threads in parallel + * - each of those has a randomised execution pattern to + * add new functors and dispatch other thread's functors + */ void verify_ThreadSafety() { CallQueue queue; - uint64_t globalSum = 0; - uint64_t checkSum = 0; - - Step step =[&]() -> uint - { - uint increment = rand() % MAX_RAND_INCMT; - uint delay = rand() % MAX_RAND_DELAY; - - queue.feed ([&]() { globalSum += increment; }); - usleep (delay); - queue.invoke(); // NOTE: typically this dequeues some other entry added during our sleep - return increment; - }; - - uint const cntSteps = rand() % MAX_RAND_STEPS; // Start a bunch of threads with random access pattern Workers workers{NUM_OF_THREADS, [&](Workers::ElementHolder& storage) { - storage.create(cntSteps, step); + storage.create(queue); } }; + // wait for termination of all threads + for (auto& worker : workers) + worker.join(); + // collect the results of all worker threads + uint64_t globalProducerSum = 0; + uint64_t globalConsumerSum = 0; for (auto& worker : workers) { - worker.join(); - checkSum += worker.localSum; + globalProducerSum += worker.producerSum; + globalConsumerSum += worker.consumerSum; } // VERIFY: locally recorded partial sums match total sum - CHECK (globalSum == checkSum); + CHECK (globalProducerSum == globalConsumerSum); } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 3c644290e..1796d6a7a 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -38,8 +38,8 @@ - - + + @@ -1047,18 +1047,20 @@ - - + + - + + - - + + +