From a1c14568493d225b171ac83b8565e76847a827e9 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 18 Jun 2023 03:50:48 +0200 Subject: [PATCH] Job-Planning: dispose of FrameCoord in pipeline and Dispatcher interface ...as a preparation for solving a logical problem with the Planning-Pipeline; it can not quite work as intended just by passing down the pair of current ticket and dependent ticket, since we have to calculate a chained calculation of job deadlines, leading up to the root ticket for a frame. My solution idea is to create the JobPlanning earlier in the pipeline, already *before* the expansion of prerequisites, and rather to integrate the representation of the dependency relation direcly into JobPlanning --- src/steam/engine/dispatch-table.cpp | 4 +- src/steam/engine/dispatch-table.hpp | 4 +- src/steam/engine/dispatcher.cpp | 1 - src/steam/engine/dispatcher.hpp | 28 +- src/steam/engine/frame-coord.hpp | 2 + src/steam/engine/job-planning.hpp | 4 +- src/steam/engine/job-ticket.cpp | 3 +- src/steam/engine/job-ticket.hpp | 2 +- .../engine/dispatcher-interface-test.cpp | 4 +- .../engine/job-planning-pipeline-test.cpp | 18 +- tests/core/steam/engine/job-planning-test.cpp | 8 +- tests/core/steam/engine/mock-dispatcher.hpp | 8 +- tests/core/steam/engine/mock-support-test.cpp | 50 ++- .../steam/fixture/fixture-segment-test.cpp | 3 +- tests/library/replaceable-item-test.cpp | 4 +- wiki/thinkPad.ichthyo.mm | 337 +++++++++++++++++- 16 files changed, 404 insertions(+), 76 deletions(-) diff --git a/src/steam/engine/dispatch-table.cpp b/src/steam/engine/dispatch-table.cpp index b46342248..874683309 100644 --- a/src/steam/engine/dispatch-table.cpp +++ b/src/steam/engine/dispatch-table.cpp @@ -36,6 +36,7 @@ namespace steam { namespace engine { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline /** */ FrameCoord DispatchTable::locateRelative (FrameCoord const&, FrameCnt frameOffset) @@ -48,9 +49,10 @@ namespace engine { { UNIMPLEMENTED ("determine when to finish a planning chunk"); } +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline JobTicket& - DispatchTable::accessJobTicket (size_t, TimeValue nominalTime) + DispatchTable::getJobTicketFor (size_t, TimeValue nominalTime) { UNIMPLEMENTED ("hook into the real implementation of the model backbone / segmentation"); } diff --git a/src/steam/engine/dispatch-table.hpp b/src/steam/engine/dispatch-table.hpp index 318059640..43f03a5f1 100644 --- a/src/steam/engine/dispatch-table.hpp +++ b/src/steam/engine/dispatch-table.hpp @@ -53,10 +53,12 @@ namespace engine { /* ==== Dispatcher interface ==== */ +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline FrameCoord locateRelative (FrameCoord const&, FrameCnt frameOffset) override; bool isEndOfChunk (FrameCnt, ModelPort port) override; +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline size_t resolveModelPort (ModelPort) override; - JobTicket& accessJobTicket (size_t, TimeValue nominalTime) override; + JobTicket& getJobTicketFor (size_t, TimeValue nominalTime) override; protected: /** timerange covered by this RenderGraph */ diff --git a/src/steam/engine/dispatcher.cpp b/src/steam/engine/dispatcher.cpp index fdd0ae443..0920fd5ea 100644 --- a/src/steam/engine/dispatcher.cpp +++ b/src/steam/engine/dispatcher.cpp @@ -37,7 +37,6 @@ namespace steam { namespace engine { Dispatcher::~Dispatcher() { } // emit VTables and Typeinfo here.... - FrameSequencer::~FrameSequencer() { } #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 :: to be refactored... diff --git a/src/steam/engine/dispatcher.hpp b/src/steam/engine/dispatcher.hpp index f6180f762..a9adbd549 100644 --- a/src/steam/engine/dispatcher.hpp +++ b/src/steam/engine/dispatcher.hpp @@ -45,7 +45,7 @@ #include "steam/play/output-slot.hpp" #include "lib/iter-tree-explorer.hpp" #include "lib/time/timevalue.hpp" -//#include "lib/nocopy.hpp" +#include "lib/nocopy.hpp" #include #include @@ -89,7 +89,7 @@ namespace engine { * @todo 6/23 API is remoulded from ground up (»Playback Vertical Slice« integration effort) */ class Dispatcher - : public FrameLocator + : util::NonCopyable { #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 :: to be refactored... /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsolete @@ -162,7 +162,6 @@ namespace engine { virtual size_t resolveModelPort (ModelPort) =0; - protected: #if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 :: to be refactored... /** core dispatcher operation: based on the coordinates of a reference point, * establish binding frame number, nominal time and real (wall clock) deadline. @@ -192,7 +191,16 @@ namespace engine { //////////// - but this leads to a lot of duplicated Timings records, unless we rewrite the TimeAnchor to be noncopyable and use a Timings const& #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 :: to be refactored... - virtual JobTicket& accessJobTicket (size_t, TimeValue nominalTime) =0; + /** + * Core Dispatcher operation: locate the appropriate Segment and + * retrieve/derive a »blueprint« for render job generation. + * @param portIDX index-number for a ModelPort [as resolved](\ref #resolveModelPort) + * @param nominalTime time of the frame to calculate, relative to Timeline origin + */ + virtual JobTicket& getJobTicketFor (size_t portIDX, TimeValue nominalTime) =0; + + /** Convenience shortcut for tests: JobTicket ⟼ Job */ + Job createJobFor (size_t portIDX, TimeValue nominalTime); }; @@ -289,9 +297,8 @@ namespace engine { SRC::transform( [portIDX](PipeFrameTick& core) -> TicketDepend { - FrameCoord frame{core.currPoint, core.frameNr, portIDX}; return {nullptr - ,& core.dispatcher->getJobTicketFor(frame) + ,& core.dispatcher->getJobTicketFor(portIDX, core.currPoint) }; })); } @@ -364,12 +371,17 @@ namespace engine { inline Dispatcher::PipelineBuilder - Dispatcher::forCalcStream(Timings timings) + Dispatcher::forCalcStream (Timings timings) { return PipelineBuilder {this, timings}; } - + inline Job + Dispatcher::createJobFor (size_t portIDX, TimeValue nominalTime) + { + return getJobTicketFor (portIDX, nominalTime) + .createJobFor (Time{nominalTime}); + } diff --git a/src/steam/engine/frame-coord.hpp b/src/steam/engine/frame-coord.hpp index 7f2895ab9..26611fe45 100644 --- a/src/steam/engine/frame-coord.hpp +++ b/src/steam/engine/frame-coord.hpp @@ -98,6 +98,7 @@ namespace engine { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline /** * Facility for producing a sequence of FrameCoord. * This interface describes the essence of generating @@ -124,6 +125,7 @@ namespace engine { protected: virtual FrameCoord locateRelative (FrameCoord const&, FrameCnt frameOffset) =0; }; +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline diff --git a/src/steam/engine/job-planning.hpp b/src/steam/engine/job-planning.hpp index bf7ee07fa..6b9428697 100644 --- a/src/steam/engine/job-planning.hpp +++ b/src/steam/engine/job-planning.hpp @@ -112,7 +112,7 @@ namespace engine { Job buildJob() { - Job job = jobTicket_.createJobFor (frameCoord_); + Job job = jobTicket_.createJobFor (frameCoord_.absoluteNominalTime); //////////////////////////////////////////////////////TICKET #1295 : somehow package and communicate the DataSink info return job; } @@ -312,6 +312,7 @@ namespace engine { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline /** * Abstraction: a Facility to establish frame coordinates * and identify and access the execution plan for this frame. @@ -340,6 +341,7 @@ namespace engine { virtual JobTicket& accessJobTicket (size_t, TimeValue nominalTime) =0; virtual bool isEndOfChunk (FrameCnt, ModelPort port) =0; }; +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline diff --git a/src/steam/engine/job-ticket.cpp b/src/steam/engine/job-ticket.cpp index 5586c6bf4..09165dee9 100644 --- a/src/steam/engine/job-ticket.cpp +++ b/src/steam/engine/job-ticket.cpp @@ -75,9 +75,8 @@ namespace engine { * after the last Builder run created this part of the render network. */ Job - JobTicket::createJobFor (FrameCoord coordinates) + JobTicket::createJobFor (Time nominalTime) { - Time nominalTime = coordinates.absoluteNominalTime; if (this->empty()) { //////////////////////////////////////////////////////////////////////////////////TICKET #1296 : can we get away just with a do-nothing functor? return Job(nopFunctor(), InvocationInstanceID(), nominalTime); diff --git a/src/steam/engine/job-ticket.hpp b/src/steam/engine/job-ticket.hpp index b34c0c2a5..82f56eafb 100644 --- a/src/steam/engine/job-ticket.hpp +++ b/src/steam/engine/job-ticket.hpp @@ -142,7 +142,7 @@ using lib::LUID; /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 : likely to become obsolete #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 :: to be refactored... - Job createJobFor (FrameCoord coordinates); + Job createJobFor (Time nominalTime); Duration getExpectedRuntime(); diff --git a/tests/core/steam/engine/dispatcher-interface-test.cpp b/tests/core/steam/engine/dispatcher-interface-test.cpp index cf7724854..d9eb8b90c 100644 --- a/tests/core/steam/engine/dispatcher-interface-test.cpp +++ b/tests/core/steam/engine/dispatcher-interface-test.cpp @@ -85,6 +85,7 @@ namespace test { /* == mock Dispatcher implementation == */ +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline FrameCoord locateRelative (FrameCoord const&, FrameCnt frameOffset) override { @@ -96,6 +97,7 @@ namespace test { { UNIMPLEMENTED ("determine when to finish a planning chunk"); } +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline size_t resolveModelPort (ModelPort modelPort) override @@ -104,7 +106,7 @@ namespace test { } JobTicket& - accessJobTicket (size_t, TimeValue nominalTime) override + getJobTicketFor (size_t, TimeValue nominalTime) override { UNIMPLEMENTED ("dummy implementation of the model backbone / segmentation"); } diff --git a/tests/core/steam/engine/job-planning-pipeline-test.cpp b/tests/core/steam/engine/job-planning-pipeline-test.cpp index b36f37832..b918a56a4 100644 --- a/tests/core/steam/engine/job-planning-pipeline-test.cpp +++ b/tests/core/steam/engine/job-planning-pipeline-test.cpp @@ -132,9 +132,8 @@ namespace test { JobTicket& ticket = seg.jobTicket(0); // get the master-JobTicket from this segment JobTicket& prereq = *(ticket.getPrerequisites()); // pull a prerequisite JobTicket - FrameCoord coord; // Frame coordinates for invocation (placeholder) - Job jobP = prereq.createJobFor(coord); // create an instance of the prerequisites for this coordinates - Job jobM = ticket.createJobFor(coord); // ...and an instance of the master job for the same coordinates + Job jobP = prereq.createJobFor(Time{0,15}); // create an instance of the prerequisites for some time(irrelevant) + Job jobM = ticket.createJobFor(Time{0,15}); // ...and an instance of the master job for the same time CHECK (MockJobTicket::isAssociated (jobP, prereq)); CHECK (MockJobTicket::isAssociated (jobM, ticket)); CHECK (not MockJobTicket::isAssociated (jobP, ticket)); @@ -146,11 +145,9 @@ namespace test { CHECK (555 == MockJob::invocationAdditionalKey (jobP)); // indicating that in practice it will activate the proper render node // (3) demonstrate mocked frame dispatcher... - coord.modelPortIDX = 1; - coord.absoluteNominalTime = Time{0,30}; MockDispatcher dispatcher; // a complete dispatcher backed by a mock Segment for the whole timeline auto [port1,sink1] = dispatcher.getDummyConnection(1); // also some fake ModelPort and DataSink entries are registered - Job jobD = dispatcher.getJobTicketFor(coord).createJobFor(coord); + Job jobD = dispatcher.createJobFor (1, Time{0,30}); CHECK (dispatcher.verify(jobD, port1, sink1)); // the generated job uses the associated ModelPort and DataSink and JobTicket } @@ -204,11 +201,10 @@ namespace test { .pullFrom (port); CHECK (not isnil (pipeline)); - CHECK (nullptr == pipeline->first); // is a top-level ticket + CHECK (nullptr == pipeline->first); // is a top-level ticket JobTicket& ticket = *pipeline->second; - FrameCoord dummy{Time::ZERO}; // actual time point is irrelevant here - Job job = ticket.createJobFor(dummy); + Job job = ticket.createJobFor(Time::ZERO); // actual time point is irrelevant here CHECK (dispatcher.verify(job, port, sink)); } @@ -244,12 +240,12 @@ namespace test { // the first element is identical to previous test CHECK (not isnil (pipeline)); CHECK (nullptr == pipeline->first); - Job job = pipeline->second->createJobFor(FrameCoord{}); + Job job = pipeline->second->createJobFor (Time::ZERO); CHECK (11 == job.parameter.invoKey.part.a); auto visualise = [](auto& pipeline) -> string { - FrameCoord frame{pipeline.currPoint}; // can access the embedded PipeFrameTick core to get "currPoint" (nominal time) + Time frame{pipeline.currPoint}; // can access the embedded PipeFrameTick core to get "currPoint" (nominal time) Job job = pipeline->second->createJobFor(frame); // looking always at the second element, which is the current JobTicket TimeValue nominalTime{job.parameter.nominalTime}; // job parameter holds the microseconds (gavl_time_t) int32_t mark = job.parameter.invoKey.part.a; // the MockDispatcher places the given "mark" here diff --git a/tests/core/steam/engine/job-planning-test.cpp b/tests/core/steam/engine/job-planning-test.cpp index b5d6d8afa..e2ad9f9d5 100644 --- a/tests/core/steam/engine/job-planning-test.cpp +++ b/tests/core/steam/engine/job-planning-test.cpp @@ -114,9 +114,9 @@ namespace test { Time nominalTime{200,0}; size_t portIDX = dispatcher.resolveModelPort (port); - FrameCoord frame{nominalTime, portIDX}; - JobTicket& ticket = dispatcher.getJobTicketFor(frame); + JobTicket& ticket = dispatcher.getJobTicketFor(portIDX, nominalTime); + FrameCoord frame{nominalTime, portIDX}; /////////////////////////////OOO replace FrameCoord JobPlanning plan{frame,ticket,sink}; Job job = plan.buildJob(); @@ -138,9 +138,9 @@ namespace test { FrameCnt frameNr{5}; Time nominalTime{200,0}; size_t portIDX = dispatcher.resolveModelPort (port); - FrameCoord frame{nominalTime, frameNr, portIDX}; - JobTicket& ticket = dispatcher.getJobTicketFor(frame); + JobTicket& ticket = dispatcher.getJobTicketFor(portIDX, nominalTime); + FrameCoord frame{nominalTime, frameNr, portIDX}; /////////////////////////////OOO replace FrameCoord JobPlanning plan{frame,ticket,sink}; // the following calculations are expected to happen.... diff --git a/tests/core/steam/engine/mock-dispatcher.hpp b/tests/core/steam/engine/mock-dispatcher.hpp index f0ae0e50d..347025dfd 100644 --- a/tests/core/steam/engine/mock-dispatcher.hpp +++ b/tests/core/steam/engine/mock-dispatcher.hpp @@ -340,7 +340,7 @@ namespace test { public: /* == mock implementation of the Dispatcher interface == */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 : likely to become obsolete +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline FrameCoord locateRelative (FrameCoord const&, FrameCnt frameOffset) override { @@ -352,7 +352,7 @@ namespace test { { UNIMPLEMENTED ("determine when to finish a planning chunk"); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1276 : likely to become obsolete +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1301 : obsoleted by rework of Dispatcher-Pipeline size_t resolveModelPort (ModelPort modelPort) override @@ -366,7 +366,7 @@ namespace test { JobTicket& - accessJobTicket (size_t portIDX, TimeValue nominalTime) override + getJobTicketFor (size_t portIDX, TimeValue nominalTime) override { auto& seg = mockSeg_[nominalTime]; return seg.jobTicket(portIDX); @@ -422,7 +422,7 @@ namespace test { TimeValue nominalTime{job.parameter.nominalTime}; size_t portIDX = resolveModelPort (port); - JobTicket& ticket = accessJobTicket (portIDX, nominalTime); + JobTicket& ticket = getJobTicketFor (portIDX, nominalTime); return isnil (ticket)? MockJob::isNopJob (job) : MockJobTicket::isAssociated (job, ticket); } diff --git a/tests/core/steam/engine/mock-support-test.cpp b/tests/core/steam/engine/mock-support-test.cpp index 23c535f66..df2002b20 100644 --- a/tests/core/steam/engine/mock-support-test.cpp +++ b/tests/core/steam/engine/mock-support-test.cpp @@ -88,8 +88,7 @@ namespace test { JobTicket& ticket = seg.jobTicket(0); - FrameCoord coord{Time(0,15)}; - Job job = ticket.createJobFor(coord); + Job job = ticket.createJobFor (Time{0,15}); CHECK (MockJobTicket::isAssociated (job, ticket)); job.triggerJob(); @@ -127,19 +126,19 @@ namespace test { void verify_MockJobTicket() { - FrameCoord coord{lib::test::randTime()}; + auto frameTime = lib::test::randTime(); // build a render job to do nothing.... - Job nopJob = JobTicket::NOP.createJobFor(coord); + Job nopJob = JobTicket::NOP.createJobFor (frameTime); CHECK (INSTANCEOF (vault::engine::NopJobFunctor, static_cast (nopJob.jobClosure))); //////////TICKET #1287 : fix actual interface down to JobFunctor (after removing C structs) - CHECK (nopJob.parameter.nominalTime == coord.absoluteNominalTime); + CHECK (nopJob.parameter.nominalTime == frameTime); InvocationInstanceID empty; ///////////////////////////////////////////////////////////////////////TICKET #1287 : temporary workaround until we get rid of the C base structs CHECK (lumiera_invokey_eq (&nopJob.parameter.invoKey, &empty)); CHECK (MockJob::isNopJob(nopJob)); // this diagnostic helper checks the same conditions as done here explicitly MockJobTicket mockTicket; CHECK (not mockTicket.empty()); - Job mockJob = mockTicket.createJobFor (coord); + Job mockJob = mockTicket.createJobFor (frameTime); CHECK ( mockTicket.verify_associated (mockJob)); // proof by invocation hash : is indeed backed by this JobTicket CHECK (not mockTicket.verify_associated (nopJob)); // ...while some random other job is not related CHECK (not MockJob::isNopJob(mockJob)); @@ -159,7 +158,6 @@ namespace test { verify_MockSegmentation() { Time someTime = lib::test::randTime(); - FrameCoord coord{someTime}; // //-----------------------------------------------------------------/// Empty default Segmentation { @@ -177,8 +175,8 @@ namespace test { JobTicket& ticket = mockSegs[someTime].jobTicket(0); CHECK (not util::isSameObject (ticket, JobTicket::NOP)); - Job someJob = ticket.createJobFor(coord); // JobTicket uses, but does not check the time given in FrameCoord - CHECK (someJob.parameter.nominalTime == _raw(coord.absoluteNominalTime)); + Job someJob = ticket.createJobFor(someTime); // JobTicket uses, but does not check the time given + CHECK (someJob.parameter.nominalTime == someTime); CHECK (MockJobTicket::isAssociated (someJob, ticket)); // but the generated Job is linked to the Closure backed by the JobTicket CHECK (not MockJob::was_invoked (someJob)); @@ -206,7 +204,7 @@ namespace test { CHECK ( util::isSameObject (seg1.jobTicket(0),JobTicket::NOP)); CHECK (not util::isSameObject (seg2.jobTicket(0),JobTicket::NOP));// this one is the active segment - Job job = seg2.jobTicket(0).createJobFor(coord); + Job job = seg2.jobTicket(0).createJobFor(someTime); CHECK (not MockJobTicket::isAssociated (job, seg1.jobTicket(0))); CHECK ( MockJobTicket::isAssociated (job, seg2.jobTicket(0))); CHECK (marker == job.parameter.invoKey.part.a); @@ -217,7 +215,7 @@ namespace test { CHECK (marker == MockJob::invocationAdditionalKey (job)); // DummyClosure is rigged such as to feed back the seed in `part.a` // and thus we can prove this job really belongs to the marked segment // create another job from the (empty) seg1 - job = seg1.jobTicket(0).createJobFor (coord); + job = seg1.jobTicket(0).createJobFor (someTime); InvocationInstanceID empty; /////////////////////////////////////////////////////////////////////TICKET #1287 : temporary workaround until we get rid of the C base structs CHECK (lumiera_invokey_eq (&job.parameter.invoKey, &empty)); // indicates that it's just a placeholder to mark a "NOP"-Job CHECK (seg1.jobTicket(0).empty()); @@ -246,7 +244,7 @@ namespace test { CHECK (Time(0,20) == s3.start()); CHECK (Time::MAX == s3.after()); - Job job = s2.jobTicket(0).createJobFor(coord); + Job job = s2.jobTicket(0).createJobFor(someTime); job.triggerJob(); CHECK (marker == MockJob::invocationAdditionalKey (job)); } @@ -289,7 +287,7 @@ namespace test { { if (segment.empty()) return 0; - Job job = segment.jobTicket(0).createJobFor(coord); + Job job = segment.jobTicket(0).createJobFor(someTime); job.triggerJob(); CHECK (MockJob::was_invoked (job)); CHECK (RealClock::wasRecently (MockJob::invocationTime (job))); @@ -314,7 +312,7 @@ namespace test { void verify_MockPrerequisites() { - FrameCoord coord; + Time someTime = lib::test::randTime(); //-----------------------------------------------------------------/// one Segment with one additional prerequisite { MockSegmentation mockSegs{MakeRec() @@ -332,8 +330,8 @@ namespace test { ++prereq; CHECK (isnil (prereq)); - Job job1 = preTicket.createJobFor (coord); - Job job2 = ticket.createJobFor (coord); + Job job1 = preTicket.createJobFor (someTime); + Job job2 = ticket.createJobFor (someTime); job1.triggerJob(); job2.triggerJob(); @@ -369,7 +367,7 @@ namespace test { .expandAll() .transform ([&](JobTicket& ticket) { - return ticket.createJobFor(coord).parameter.invoKey.part.a; + return ticket.createJobFor(someTime).parameter.invoKey.part.a; }); @@ -391,7 +389,6 @@ namespace test { void verify_MockDispatcherSetup() { - FrameCoord frame{Time{0,30}}; { MockDispatcher dispatcher; // automatically generates some fake connection points... @@ -409,10 +406,11 @@ namespace test { CHECK (0 == dispatcher.resolveModelPort(port0)); CHECK (1 == dispatcher.resolveModelPort(port1)); - frame.modelPortIDX = 0; - Job job0 = dispatcher.getJobTicketFor(frame).createJobFor(frame); - frame.modelPortIDX = 1; - Job job1 = dispatcher.getJobTicketFor(frame).createJobFor(frame); + Time frameTime{0,30}; + size_t modelPortIDX = 0; + Job job0 = dispatcher.createJobFor (modelPortIDX, frameTime); + modelPortIDX = 1; + Job job1 = dispatcher.createJobFor (modelPortIDX, frameTime); CHECK (dispatcher.verify(job0, port0, sink0)); CHECK (dispatcher.verify(job1, port1, sink1)); } @@ -426,11 +424,9 @@ namespace test { .attrib("start", Time{0,10}) // second segment covers 10s … +Time::MAX .genNode()}; - frame.modelPortIDX = 1; - frame.absoluteNominalTime = Time{0,5}; - Job job0 = dispatcher.getJobTicketFor(frame).createJobFor(frame); - frame.absoluteNominalTime = Time{0,25}; - Job job1 = dispatcher.getJobTicketFor(frame).createJobFor(frame); + size_t modelPortIDX = 1; + Job job0 = dispatcher.createJobFor (modelPortIDX, Time{0,5}); + Job job1 = dispatcher.createJobFor (modelPortIDX, Time{0,25}); CHECK (11 == job0.parameter.invoKey.part.a); CHECK (22 == job1.parameter.invoKey.part.a); diff --git a/tests/core/steam/fixture/fixture-segment-test.cpp b/tests/core/steam/fixture/fixture-segment-test.cpp index f4e100cf2..98431ef3c 100644 --- a/tests/core/steam/fixture/fixture-segment-test.cpp +++ b/tests/core/steam/fixture/fixture-segment-test.cpp @@ -110,8 +110,7 @@ namespace test { // verify mapped JobTicket is assembled according to above spec... auto getMarker = [](JobTicket& ticket) { - engine::FrameCoord dummyFrame; - Job job = ticket.createJobFor(dummyFrame); + Job job = ticket.createJobFor(Time::ANYTIME); return job.parameter.invoKey.part.a; }; diff --git a/tests/library/replaceable-item-test.cpp b/tests/library/replaceable-item-test.cpp index e93f14fc5..26ef5669f 100644 --- a/tests/library/replaceable-item-test.cpp +++ b/tests/library/replaceable-item-test.cpp @@ -101,8 +101,8 @@ namespace test{ virtual void run (Arg) { - ulong l1 (rand() % 1000); - ulong l2 (rand() % 1000); + ulong l1 (1 + rand() % 1000); + ulong l2 (1 + rand() % 1000); string s1 (randStr(50)); string s2 (randStr(50)); const char* cp (s1.c_str()); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index d4e2618d4..7ab77e458 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -64955,7 +64955,7 @@ - + @@ -70013,7 +70013,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -70026,6 +70026,40 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +

+ ...damit könnten die FrameCoord ihre Bestimmung gefunden haben, denn in diesem Bezug sind auch FrameNr und nominalTime nicht redundant (Quantisierung!), sondern machen die Grid-Anwendung explizit +

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

+ Fazit: haben keine Rolle mehr und werden aufgegeben +

+ +
+
@@ -75722,9 +75756,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + @@ -75737,7 +75771,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -75751,17 +75785,22 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + + + + + + @@ -75778,6 +75817,284 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + +

+ Problem : habe nur JobTicket des unmittelbaren  Vorgängers +

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

+ weil das die einzige Stelle ist in der zugleich Dependent und Dependency zugänglich sind +

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

+ da im JobPlanning nochmal eine JobTicket& liegt, sind die zwei bisher im darunter liegenden Tupel gespeicherten JobTicket* eigentlich redundant und werden nur für die Explorer-Mechanik gebraucht +

+ +
+
+ + + + + + +

+ weil nun auf jeder Ebene im Explorer-Stack eine JobPlanning-Instanz liegt, und zwar dort im ItemWrapper für den jeweiligen TransformIterator (der die Explorer-Funktion implementiert) +

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

+ Wenn man die Daten entsprechend reorganisiert und dadurch die Redundanzen in der Pipeline minimiert kann der Optimiser viel machen, da (private) Referenzen überhaupt nicht repräsentiert werden müssen, sofern die referenzierte Quelle (wie hier) stabil im gleichen Objekt liegt. Wenn ich richtig schätze, habe ich mit dem Umbau nur einen »slot« mehr Speicher verbraucht (weil drei redundante »slots« wegfallen können) +

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

+ ...denn sonst würde es genau zu rekursiven kaskadierenden (exponentiell aufwendigen) Aufrufen der Deadline-Berechnungs-Logik kommen; um das Caching zu steuern, kann ich einen Marker-Wert Time::NEVER verwenden +

+ +
+ +
+ + + + + + +

+ AUA: dieser parent-Pointer war bisher sogar eine dangling reference — er zeigte nämlich auf einen Pointer im Stack-Frame des λ-Aufrufs, der aber gar nicht mehr existiert, wenn man den Transform-Iterator auswertet. Soschnellkannsgehen +

+ +
+
+ + + + + + +

+ ...denn sonst müßte ich sie in eine λ-Closure binden, was aber für zwei der drei Felder redundate Storage wäre; es macht auch sonst Sinn, wenn der Tick-Generator eben auf den FrameCoord arbeitet +

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

+ dann müssen die FrameCoord jetzt sterben +

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

+ verwendet nur absoluteNominalTime +

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

+ das ist die einzige Verwendung von zwei Feldern +

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

+ Das ist genau der Grund warum sie jetzt zum Problem werden: diese Funktion erzeugt FrameCoord, die irgendwo leben müssen, und das bloß, um den einen Aufruf zu machen. Das bestätigt die Enscheidung, sie zurückzubauen +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + + +
+
+
+
+ + + + + + + + + +
@@ -76568,7 +76885,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +