From 4f37b0412cf7c59c4b860c55683b3fa20ae77836 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 23 May 2023 06:40:18 +0200 Subject: [PATCH] Job-Planning: finally complete the MockSegmentation tests Last testcase: add deeply nested Prerequisites. Turns out that the allocator must be able to handle re-entrant allocations, which std::deque can not fulfil. Thus using std::list here for the Mock implementation. In the end, the real allocations will be done by our custom allocator (AllocationCluster), which can be arranged easily to support re-entrant allocation calls (since the whole point is to just place those objects into a pre-allocated large block and only de-allocate them later in one sway. Thus the allocator does not need to wait for the object constructor to finish, which trivially allows for re-entrant calls) --- src/steam/engine/job-ticket.hpp | 3 +- tests/core/steam/engine/mock-dispatcher.hpp | 12 +- tests/core/steam/engine/mock-support-test.cpp | 151 ++------- wiki/thinkPad.ichthyo.mm | 305 ++++++++++++++++-- 4 files changed, 314 insertions(+), 157 deletions(-) diff --git a/src/steam/engine/job-ticket.hpp b/src/steam/engine/job-ticket.hpp index 41e37e97a..c6f96c0dc 100644 --- a/src/steam/engine/job-ticket.hpp +++ b/src/steam/engine/job-ticket.hpp @@ -151,7 +151,8 @@ using lib::LUID; auto getPrerequisites (uint slotNr =0) const { - return lib::transformIterator (provision_[slotNr].requirements.begin() + return lib::transformIterator (this->empty()? Prerequisites::iterator() + : provision_[slotNr].requirements.begin() ,[](Prerequisite& prq) -> JobTicket const& { return prq.descriptor; diff --git a/tests/core/steam/engine/mock-dispatcher.hpp b/tests/core/steam/engine/mock-dispatcher.hpp index 1fc89d84f..865ce04f9 100644 --- a/tests/core/steam/engine/mock-dispatcher.hpp +++ b/tests/core/steam/engine/mock-dispatcher.hpp @@ -41,6 +41,7 @@ ////#include "lib/format-cout.hpp" #include "lib/diff/gen-node.hpp" #include "lib/depend.hpp" +#include "lib/linked-elements.hpp" #include "lib/itertools.hpp" //#include "lib/iter-tree-explorer.hpp" //#include "lib/util-coll.hpp" @@ -53,7 +54,8 @@ //#include //#include #include -#include +#include +//#include //using test::Test; //using util::isnil; @@ -82,7 +84,7 @@ namespace test { // using play::Timings; using lib::HashVal; using std::make_tuple; - using std::deque; +// using std::deque; ///////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1294 : organisation of namespaces / includes?? using fixture::Segmentation; @@ -197,7 +199,9 @@ namespace test { class MockSegmentation : public Segmentation { - std::deque tickets_; + // simulated allocator; + // must be able to handle re-entrant allocations + std::list tickets_; public: MockSegmentation() @@ -241,7 +245,7 @@ namespace test { { return tickets_.emplace_back (buildSeed(spec) ,buildPrerequisites(spec)); - } + } // Warning: re-entrant invocation of emplace_back }; diff --git a/tests/core/steam/engine/mock-support-test.cpp b/tests/core/steam/engine/mock-support-test.cpp index 1e3fa2ead..cff471cdb 100644 --- a/tests/core/steam/engine/mock-support-test.cpp +++ b/tests/core/steam/engine/mock-support-test.cpp @@ -26,28 +26,18 @@ #include "lib/test/run.hpp" +#include "lib/test/test-helper.hpp" #include "steam/engine/mock-dispatcher.hpp" #include "vault/engine/nop-job-functor.hpp" #include "vault/engine/dummy-job.hpp" #include "lib/iter-tree-explorer.hpp" #include "lib/util-tuple.hpp" #include "lib/util.hpp" -#include "lib/format-cout.hpp" -#include "lib/test/test-helper.hpp" -#include "lib/meta/duck-detector.hpp"///////////////TODO WIP + using test::Test; -///////////////////////////////////////////////////////TODO WIP for investigation -namespace lib { -namespace iter_explorer { - template - using DecoTraits = _DecoratorTraits; - template - using ExpoTraits = _ExpanderTraits; -}} -///////////////////////////////////////////////////////TODO WIP for investigation namespace steam { namespace engine{ namespace test { @@ -58,41 +48,6 @@ namespace test { using util::isSameObject; using util::seqTuple; -///////////////////////////////////////////////////////TODO WIP for investigation - template - struct ReBind - { - using type = typename U::type; - }; -// template -// struct has_TypeResult : std::false_type { }; -// -// template -// struct has_TypeResult::type> : std::true_type { }; -// -// template -// struct has_TypeResult : std::true_type { }; - -// using lib::meta::Yes_t; -// using lib::meta::No_t; -// -// template -// class HasNested_type -// { -// template -// static Yes_t check(typename X::type *); -// template -// static Yes_t check(typename X::Type *); -// template -// static No_t check(...); -// -// public: -// static const bool value = (sizeof(Yes_t)==sizeof(check(0))); -// }; -// -// template -// struct has_TypeResult : std::bool_constant::value> { }; -///////////////////////////////////////////////////////TODO WIP for investigation /**********************************************************************//** @@ -378,98 +333,42 @@ namespace test { CHECK (23 == DummyJob::invocationAdditionalKey (job1)); CHECK (11 == DummyJob::invocationAdditionalKey (job2)); } - //-----------------------------------------------------------------/// deep nested prerequisite + //-----------------------------------------------------------------/// a tree of deep nested prerequisites { MockSegmentation mockSegs{MakeRec() - .attrib("mark", 11) - .scope(MakeRec() - .attrib("mark",23) - .genNode()) + .attrib("mark", 11) + .scope(MakeRec() + .attrib("mark",33) + .scope(MakeRec() + .attrib("mark",55) + .genNode() + ,MakeRec() + .attrib("mark",44) + .genNode() + ) + .genNode() + ,MakeRec() + .attrib("mark",22) + .genNode()) .genNode()}; - using RTick = std::reference_wrapper; auto start = singleValIterator (mockSegs[Time::ZERO].jobTicket()); - using SrC = lib::iter_explorer::BaseAdapter >; - - auto bunny = [](JobTicket const& ticket) + auto it = lib::explore(start) + .expand ([](JobTicket const& ticket) { return ticket.getPrerequisites(); -// return lib::transformIterator(ticket.getPrerequisites() -// ,[](JobTicket const& preq) -> JobTicket* -// { return unConst(&preq); } -// ); - }; - using ExIt = decltype(bunny(std::declval())); - - using Funny = std::function; - Funny funny = bunny; - - using ExpandedChildren = typename lib::iter_explorer::_FunTraits::Res; - - - using ResIter = typename lib::iter_explorer::DecoTraits::SrcIter; -// lib::test::TypeDebugger buggy; - using ResIterVal = typename ResIter::value_type; - using SrcIterVal = typename SrC::value_type; -// lib::test::TypeDebugger buggy; -// lib::test::TypeDebugger bugggy; - - using FunResTrait = lib::iter_explorer::_FunTraits; - using FunArg = typename FunResTrait::Arg; - using ArgAdaptRes = typename FunResTrait::ArgAdapter; - static_assert(std::is_convertible()); -// lib::test::TypeDebugger buggy; - -// using ResCore = iter_explorer::Expander; - using ResCore = lib::iter_explorer::Expander; - -// using ExResIter = typename lib::iter_explorer::DecoTraits::SrcIter; -// static_assert(lib::meta::can_IterForEach::value); -// static_assert(lib::meta::can_STL_ForEach::value); - struct Murks - { - using type = void; - }; - struct Gurks : Murks { }; - static_assert(lib::meta::has_TypeResult()); - using Wootz = std::common_type; - using Wauzz = typename Wootz::type; -// lib::test::TypeDebugger bully; - - static_assert(lib::meta::has_TypeResult>()); -// static_assert(HasNested_type::value); -// static_assert(HasNested_type::value); -// static_assert(has_TypeResult()); - - using ExiTrait = lib::iter_explorer::ExpoTraits; - using WrapIter = typename lib::iter_explorer::DecoTraits::SrcIter; -// lib::test::TypeDebugger::reference> bully; -// static_assert(std::is_const_v); -// static_assert(std::is_const_v); -// static_assert(std::is_const_v); -// lib::test::TypeDebugger> bully; -// lib::test::TypeDebugger bully; -// lib::test::TypeDebugger bully; -// lib::test::TypeDebugger bully; - - - auto it = lib::explore(start) -// .transform ([](RTick t) -> JobTicket const& -// { -// return t.get(); -// }) - .expand (funny) + }) .expandAll() .transform ([&](JobTicket const& ticket) { return ticket.createJobFor(coord).parameter.invoKey.part.a; }); - cout << util::join(it,"-") < - + - + - - + + - + @@ -69950,8 +69950,8 @@ - - + + @@ -69992,18 +69992,24 @@ - - - - + + + + + + + + + - + + - - + + - - + + @@ -70089,7 +70095,7 @@ - + @@ -70212,18 +70218,18 @@ - - + + - + - + @@ -70299,7 +70305,7 @@ - + @@ -70465,7 +70471,7 @@ - + @@ -71260,8 +71266,8 @@ - - + + @@ -71344,7 +71350,7 @@ - + @@ -71521,6 +71527,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ und korrumpiert daher die laufende Berechnung auf top-Level +

+ +
+ +
+
+
+
+ + + + + + + + + + +

+ Prerequisites sind privat in JobTicket +

+ +
+
+ + + + + + +

+ deshalb können sie erst im Konstruktor gebaut werden +

+ +
+
+ + + + + + +

+ außerdem gibt es kein Mutatons-API +

+ +
+
+ + + + + + +

+ also müssen sie auch bereits im Konstruktor vollständig gebaut werden +

+ +
+
+ + + + + + +

+ und obendrein ist JobTicket non-Copyable +

+ +
+
+ + + + + + +

+ also muß es per emplace erzeugt werden +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +

+ Entscheidung im Hinblick auf den AllocationCluster +

+ +
+ + + + + +

+ das kommt nicht von Ungefähr: dieses ganze (relativ fragile) Setup mit den Referenzen in LinkedElements mache ich ganz bewußt, weil am Ende ein Allocation-Schema beabsichtigt ist, bei dem viele Elemente in kurzer Zeit in einen gemeinsam allozierten großen Block gelegt werden; dort bleiben sie bestehen, selbst nachdem ihr Destruktor aufgerufen wurde. Die De-Allokation erfolgt auf einmal, zusammen mit dem gesamten Segment +

+ +
+ + +
+
+
+ + + + + + + + +

+ das ist eine »bastel-Lösung« +

+ +
+ +
+ + + + + + + + + + +

+ list::emplace_back  funktioniert +

+ + +
+
+
+
+
+ + +