Scheduler: Layer-2 complete and tested (see #1326)

* the implementation logic of the Scheduler is essentially complete now
 * all functionality necessary for the worker-function has been demonstrated

As next step, the »Scheduler Service« can be assembled from the two
Implementation Layers, the Activity-Language and the `BlockFlow` allocator
This should then be verified by a multi-threaded integration test...
This commit is contained in:
Fischlurch 2023-10-19 01:49:08 +02:00
parent 10a2c6908c
commit 9ce3ad3d72
7 changed files with 319 additions and 180 deletions

View file

@ -54,7 +54,7 @@ namespace gear {
* Term builder and execution framework to perform chains of _scheduler Activities_.
* These are the verbs of a low-level execution language for render jobs; individual
* \ref Activity records are managed by the \ref BlockFlow allocation scheme and maintained
* until expiration their deadline. To enact a render job, a connection of Activities
* until expiration of their deadline. To enact a render job, a connection of Activities
* will be suitably wired, and the entry point to start execution can be instructed
* into the Scheduler.
*
@ -65,7 +65,7 @@ namespace gear {
* - the static function ActivityLang::dispatchChain() provides the execution logic
* for _activating_ a chain of Activities successively.
* - for real usage, this execution environment needs some functionality implemented
* in the scheduler, which -- for the purpose of Activity activation -- is abstracted
* in the scheduler, which for the purpose of Activity activation is abstracted
* as an *Execution Context* with the following operations
* ** λ-post : hand over a chain of Activities for (time bound) activation
* ** λ-work : signal start of media processing and then leave »management mode«

View file

@ -28,10 +28,10 @@
** temporal limits (deadlines) and dependency constraints. A predefined
** and fixed set of _Activity verbs_ defines atomic operations the engine
** is able to perform, directed by the scheduler. Complex calculation
** tasks are constructed from interconnected activities, passing through
** tasks are constructed from interconnected activities, passed through
** the messaging and priority queue of the scheduler. While an Activity
** is in processing, the corresponding descriptor data record is maintained
** by the BlockStream custom memory manager.
** by the \ref BlockStream custom memory manager.
**
** # Performing Activities
**
@ -50,7 +50,9 @@
** single threaded operation with the ability to mutate the scheduler queue;
** typically this happens after de-queuing an Activity from the priority queue
** and leads then to Activation of the retrieved Activity; however, it can also
** happen _right now_ -- when the indicated time has passed.
** happen _right away_ when the indicated time has passed.
** - Activity::INVOKE represents the relevant case of a [»Render Job«](\ref JobFunctor)
** and is typically performed by [workers running concurrently](\ref WorkForce)
** - Activity::notify receives a message/trigger from another prerequisite Activity
**
** @see SchedulerActivity_test
@ -133,7 +135,7 @@ namespace gear {
class Hook
{
public:
virtual ~Hook(); ///< this is an interface
virtual ~Hook(); ///< this is an interface
/**
* Callback on activation of the corresponding HOOK-Activity.

View file

@ -24,12 +24,45 @@
/** @file scheduler-commutator.hpp
** Layer-2 of the Scheduler: coordination and interaction of activities.
** This is the upper layer of the implementation and provides high-level functionality.
**
** Rendering Activities are represented as a chain of \ref Activity verbs (records),
** which are interconnected to create a low-level _execution language._ The prime
** Activity obviously is to \ref Activity::Verb::INVOKE a \ref JobFunctor encapsulating
** media processing operations; further Activity verbs provide building blocks for
** execution logic, to check preconditions, notify follow-up tasks after calculation
** results are available and to control the scheduling process itself. The Scheduler
** as a service allows to execute Activities while observing time and dependency
** constraints and in response to external events (notably after IO callback).
**
** Activity records are tiny data records (standard layout and trivially constructible);
** they are comprised of a verb tag and a `union` for variant parameter storage, and will
** be managed _elsewhere_ relying on the \ref BlockFlow allocation scheme. Within the
** scheduler queues and execution environment it is thus sufficient to pass `Activity*`.
** While the actual media processing is performed concurrently by a \ref WorkForce with
** a pool of _actively pulling workers,_ any allocations and changes to internal state
** and data structures of the Scheduler itself must be protected against data corruption
** by concurrency. The intended usage scenario involves media data computations which
** are by several orders of magnitude more expensive than all the further internal
** management operations. Thus the design of the Scheduler relies on simple mutual
** exclusion (implemented by atomic lock, see \ref SchedulerCommutator::groomingToken_).
** Each worker in search for the next task will first _acquire_ the Grooming-Token, then
** execute some internal Activities until encountering an actual media computation JobFunctor.
** At this point, the execution will switch from _»grooming mode«_ into _work mode;_ the
** worker _drops_ the Grooming-Token at this point and will then refrain from touching
** any further Scheduler internals. Finally, after completion of the current Render Job,
** the worker will again contend for the Grooming-Token to retrieve more work.
**
** In typical usage, Layer-2 of the Scheduler will perform the following operations
** - accept and enqueue new task descriptions (as chain-of-Activities)
** - retrieve the most urgent entry from Layer-1
** - use the [Activity Language environment](\ref ActivityLang) to _perform_
** the retrieved chain within some worker thread; this is called _dispatch_
** The central cross road of this implementation is the #postDispatch function.
** @see SchedulerCommutator::acquireGroomingToken()
** @see SchedulerCommutator::findWork()
** @see SchedulerCommutator::postDispatch()
** @see SchedulerCommutator_test
** @see scheduler.hpp usage
**
** @todo WIP-WIP-WIP 6/2023 »Playback Vertical Slice«
**
**
*/
@ -44,10 +77,6 @@
#include "lib/time/timevalue.hpp"
#include "lib/nocopy.hpp"
//#include "lib/symbol.hpp"
//#include "lib/util.hpp"
//#include <string>
#include <thread>
#include <atomic>
@ -60,13 +89,14 @@ namespace gear {
using std::memory_order::memory_order_relaxed;
using std::memory_order::memory_order_acquire;
using std::memory_order::memory_order_release;
// using util::isnil;
// using std::string;
/**
/*************************************************************//**
* Scheduler Layer-2 : execution of Scheduler Activities.
*
* - protect data structures through exclusive »grooming mode«
* - use the underlying Layer-1 to retrieve the most urgent work
* - dispatch and execute a chain of _Render Activities_
* @see SchedulerInvocation (Layer-1)
* @see SchedulerCommutator_test
*/
@ -76,33 +106,32 @@ namespace gear {
using ThreadID = std::thread::id;
atomic<ThreadID> groomingToken_{};
public:
// explicit
SchedulerCommutator()
{ }
auto thisThread() { return std::this_thread::get_id(); }
public:
SchedulerCommutator() = default;
/**
* acquire the right to perform internal state transitions.
* @return `true` if this attempt succeeded
* @note only one thread at a time can acquire the GoomingToken successfully.
* @remark only if _testing and branching_ on the return value, this also constitutes
* also sync barrier; _in this case you can be sure_ to see the real values
* a valid sync barrier; _in this case you can be sure_ to see the real values
* of any scheduler internals and are free to manipulate.
*/
bool
acquireGoomingToken() noexcept
{
ThreadID expect_noThread; // expect no one else to be in...
ThreadID myself = std::this_thread::get_id();
return groomingToken_.compare_exchange_strong (expect_noThread, myself
return groomingToken_.compare_exchange_strong (expect_noThread, thisThread()
,memory_order_acquire // success also constitutes an acquire barrier
,memory_order_relaxed // failure has no synchronisation ramifications
);
}
/**
* relinquish the right for internal transitions.
* relinquish the right for internal state transitions.
* @remark any changes done to scheduler internals prior to this call will be
* _sequenced-before_ anything another thread does later, _bot only_
* if the other thread first successfully acquires the GroomingToken.
@ -110,7 +139,7 @@ namespace gear {
void
dropGroomingToken() noexcept
{ // expect that this thread actually holds the Grooming-Token
REQUIRE (groomingToken_.load(memory_order_relaxed) == std::this_thread::get_id());
REQUIRE (groomingToken_.load(memory_order_relaxed) == thisThread());
const ThreadID noThreadHoldsIt;
groomingToken_.store (noThreadHoldsIt, memory_order_release);
}
@ -130,15 +159,14 @@ namespace gear {
* Decide if Activities shall be performed now and in this thread.
* @param when the indicated time of start of the first Activity
* @param now current scheduler time
* @return allow dispatch if acquired GroomingToken and time is due
* @warning accesses current ThreadID and changes GroomingToken state
* @return allow dispatch if time is due and GroomingToken was acquired
* @warning accesses current ThreadID and changes GroomingToken state.
*/
bool
decideDispatchNow (Time when, Time now)
{
auto myself = std::this_thread::get_id();
return (when <= now)
and (holdsGroomingToken (myself)
and (holdsGroomingToken (thisThread())
or acquireGoomingToken());
}
@ -147,7 +175,7 @@ namespace gear {
Activity*
findWork (SchedulerInvocation& layer1, Time now)
{
if (holdsGroomingToken(std::this_thread::get_id())
if (holdsGroomingToken (thisThread())
or acquireGoomingToken())
{
layer1.feedPrioritisation();
@ -190,7 +218,7 @@ namespace gear {
if (decideDispatchNow (when, now))
return ActivityLang::dispatchChain (*chain, executionCtx);
else
if (holdsGroomingToken(std::this_thread::get_id()))
if (holdsGroomingToken (thisThread()))
layer1.feedPrioritisation (*chain, when);
else
layer1.instruct (*chain, when);
@ -199,6 +227,5 @@ namespace gear {
};
}} // namespace vault::gear
#endif /*SRC_VAULT_GEAR_SCHEDULER_COMMUTATOR_H_*/

View file

@ -23,14 +23,21 @@
/** @file scheduler-invocation.hpp
** Layer-1 of the Scheduler: queueing and prioritisation of activities.
** This is the lower layer of the implementation and provides low-level functionality.
**
** This is the lower layer of the implementation and provides the data structures
** necessary to implement low-level scheduling functionality. The Scheduler operates
** on Activity records maintained elsewhere, in the \ref BlockFlow allocation scheme.
** Layer-2 adds the ability to _perform_ these _Render Activities,_ constituting a
** low-level execution language. Since the services of the Scheduler are used in
** a multi-threaded context, new entries will be passed in through an lock-free
** _Instruction Queue._ The actual time based prioritisation is achieved by the
** use of a _Priority Queue_ which however must be concurrency protected.
** The Layer-2 thus assures that _mutating operations_ are performed
** exclusively from a special »grooming mode« (management mode).
** @see SchedulerCommutator::findWork()
** @see SchedulerCommutator::postDispatch()
** @see SchedulerInvocation_test
** @see SchedulerUsage_test integrated usage
** @see scheduler.cpp implementation details
**
** @todo WIP-WIP-WIP 10/2023 »Playback Vertical Slice«
**
**
*/
@ -40,12 +47,9 @@
#include "vault/common.hpp"
#include "lib/nocopy.hpp"
//#include "lib/symbol.hpp"
#include "vault/gear/activity.hpp"
#include "lib/time/timevalue.hpp"
//#include "lib/util.hpp"
//#include <string>
#include <queue>
#include <boost/lockfree/queue.hpp>
#include <utility>
@ -54,8 +58,6 @@ namespace vault{
namespace gear {
using lib::time::Time;
// using util::isnil;
// using std::string;
using std::move;
namespace error = lumiera::error;
@ -65,15 +67,18 @@ namespace gear {
}
/**
/***************************************************//**
* Scheduler Layer-1 : time based dispatch.
*
* Manages pointers to _Render Activity records._
* - new entries passed in through the #instruct_ queue
* - time based prioritisation in the #priority_ queue
* @see Scheduler
* @see SchedulerInvocation_test
*/
class SchedulerInvocation
: util::NonCopyable
{
/** @internal data record passed through the queues */
struct ActOrder
{
int64_t waterlevel{0};
@ -96,6 +101,7 @@ namespace gear {
InstructQueue instruct_;
PriorityQueue priority_;
public:
SchedulerInvocation()
: instruct_{INITIAL_CAPACITY}
@ -117,7 +123,7 @@ namespace gear {
/**
* Pick up all new Activities from the entrance queue
* and enqueue them according to time order
* and enqueue them to be retrieved ordered by start time.
*/
void
feedPrioritisation()
@ -131,6 +137,7 @@ namespace gear {
/**
* Feed the given Activity directly into time prioritisation,
* effectively bypassing the thread dispatching entrance queue.
* @remark Layer-2 uses this shortcut when in »grooming mode«.
*/
void
feedPrioritisation (Activity& activity, Time when)
@ -151,9 +158,10 @@ namespace gear {
}
/**
* If there is an Activity to process now, pick it from the scheduling queue
* Retrieve from the scheduling queue the Activity with earliest start time.
* @return `nullptr` if the prioritisation queue is empty,
* else a pointer to the most urgent Activity dequeued thereby.
* @remark Activity Records are managed by the \ref BlockFlow allocator.
*/
Activity*
pullHead()
@ -164,6 +172,9 @@ namespace gear {
return activity;
}
/* ===== query functions ===== */
/** Determine if there is work to do right now */
bool
isDue (Time now) const
@ -185,7 +196,7 @@ namespace gear {
{
return priority_.empty()? Time::ANYTIME
: Time{TimeValue{priority_.top().waterlevel}};
} //Note: 64-bit waterLevel corresponds to µ-Ticks
} //Note: 64-bit waterLevel corresponds to µ-Ticks
private:
static int64_t

View file

@ -26,7 +26,7 @@ END
PLANNED "Scheduler Layer-2" SchedulerCommutator_test <<END
TEST "Scheduler Layer-2" SchedulerCommutator_test <<END
return: 0
END

View file

@ -33,28 +33,23 @@
#include "lib/format-cout.hpp"
#include "lib/thread.hpp"
#include "lib/util.hpp"
#include "lib/test/diagnostic-output.hpp"///////////////////////////TODO TOD-Oh
//#include <utility>
#include <chrono>
using test::Test;
using lib::test::threadBenchmark;
//using std::move;
using util::isSameObject;
namespace vault{
namespace gear {
namespace test {
// using lib::time::FrameRate;
// using lib::time::Offset;
using lib::time::Time;
using lib::time::FSecs;
using std::atomic_bool;
using lib::ThreadHookable;
using lib::thread::ThreadWrapper;
using util::isSameObject;
using std::unique_ptr;
using std::make_unique;
@ -62,18 +57,10 @@ namespace test {
using std::this_thread::sleep_for;
using std::chrono_literals::operator ""us;
namespace {// Test parameters
const size_t NUM_THREADS = 20;
namespace { // Load test parameters
const size_t NUM_THREADS = 20; ///< @see #torture_GroomingToken()
const size_t REPETITIONS = 100;
inline void
___ensureGroomingTokenReleased(SchedulerCommutator& sched)
{
auto myself = std::this_thread::get_id();
CHECK (not sched.holdsGroomingToken(myself));
CHECK (sched.acquireGoomingToken());
sched.dropGroomingToken();
}
}
@ -81,8 +68,23 @@ namespace test {
/******************************************************************//**
* @test Scheduler Layer-2: dependency notification and triggering.
* @test Scheduler Layer-2: coordination of Activity execution.
* @remark Layer-2 combines the queue data structure from Layer-1 with the
* »Activity Language« to allow _performing_ of Render Activities.
* This test verifies the proper integration of these building blocks
* - the _Grooming-Token_ is an atomic lock tied to current thread-id;
* it will be acquired for all operations manipulating internal state
* - the \ref ActivityDetector is used as a test helper to record calls
* and to verify the Activities are indeed activated as expected
* - the #integratedWorkCycle() walks through all the steps typically
* happening when a Render-Job is first planned and scheduled, and
* then retrieved and executed by the \ref WorkForce. However, these
* steps are invoked directly here, and with suitable instrumentation
* to watch processing in detail
* - the complete Scheduler functionality is assembled one level higher
* in the [Scheduler-Service](\ref scheduler.hpp)...
* @see SchedulerActivity_test
* @see ActivityDetector_test
* @see SchedulerUsage_test
*/
class SchedulerCommutator_test : public Test
@ -91,41 +93,43 @@ namespace test {
virtual void
run (Arg)
{
// demonstrateSimpleUsage();
// verify_GroomingToken();
// torture_GroomingToken();
// verify_DispatchDecision();
demonstrateSimpleUsage();
verify_GroomingToken();
torture_GroomingToken();
verify_DispatchDecision();
verify_findWork();
verify_postDispatch();
integratedWorkCycle();
}
/** @test TODO demonstrate a simple usage scenario
* @todo WIP 10/23 define 🔁 implement
/** @test demonstrate a simple usage scenario
*/
void
demonstrateSimpleUsage()
{
SchedulerInvocation queues;
SchedulerInvocation queue;
SchedulerCommutator sched;
Activity activity;
Time when{1,2,3};
// prepare scenario: some activity is enqueued
queues.instruct (activity, when);
Time when{1,2};
// use the ActivityDetector for test instrumentation...
ActivityDetector detector;
Time now = detector.executionCtx.getSchedTime();
// prepare scenario: some activity is enqueued
queue.instruct (activity, when);
sched.postDispatch (sched.findWork(queue,now), now, detector.executionCtx,queue);
CHECK (detector.verifyInvocation("CTX-tick").arg(now));
CHECK (queue.empty());
// sched.postDispatch (sched.findWork(queues), detector.executionCtx); ///////////////////////OOO findWork umschreiben
// cout << detector.showLog()<<endl; // HINT: use this for investigation...
}
/** @test verify logic to control concurrent execution
* @todo WIP 10/23 define implement
*/
void
verify_GroomingToken()
@ -143,11 +147,22 @@ namespace test {
___ensureGroomingTokenReleased(sched);
}
/** @internal helper to ensure consistent Grooming-Token state */
static void
___ensureGroomingTokenReleased (SchedulerCommutator& sched)
{
auto myself = std::this_thread::get_id();
CHECK (not sched.holdsGroomingToken(myself));
CHECK (sched.acquireGoomingToken());
sched.dropGroomingToken();
}
/** @test ensure the GroomingToken mechanism indeed creates an
* exclusive section protected against concurrent corruption.
* @todo WIP 10/23 define implement
/** @test ensure the GroomingToken mechanism indeed creates mutual
* exclusion to protected against concurrent corruption.
* @remark uses lib::test::threadBenchmark() to put the test-subject
* under pressure by strongly contended parallel execution.
*/
void
torture_GroomingToken()
@ -165,7 +180,7 @@ namespace test {
auto protected_sum = [&](size_t i) -> size_t
{
while (not sched.acquireGoomingToken())
yield();
yield(); // contend until getting exclusive access
pause_and_sum(i);
sched.dropGroomingToken();
return 1;
@ -189,7 +204,7 @@ namespace test {
unique_ptr<ThreadHookable> groomingHog_;
using Launch = ThreadHookable::Launch;
/** @internal Helper to block the GroomingToken in another thread */
/** @internal Helper to block the GroomingToken from another thread */
void
blockGroomingToken (SchedulerCommutator& sched)
{
@ -206,10 +221,10 @@ namespace test {
sched.dropGroomingToken();
}}
.atExit([&](ThreadWrapper& handle)
{
handle.detach_thread_from_wrapper();
groomingHog_.reset();
})
{
handle.detach_thread_from_wrapper();
groomingHog_.reset();
})
.threadID("grooming-hog"));
sleep_for (500us);
}
@ -225,9 +240,10 @@ namespace test {
/** @test verify the decision logic where and when to perform
* the dispatch of an Scheduler Activity chain.
* @todo WIP 10/23 define implement
/** @test verify the logic to decide where and when to perform
* the dispatch of a Scheduler Activity chain.
*/
void
verify_DispatchDecision()
@ -241,17 +257,17 @@ namespace test {
Time now{t2};
auto myself = std::this_thread::get_id();
CHECK (sched.decideDispatchNow (t1, now));
CHECK (sched.decideDispatchNow (t1, now)); // time is before now => good to execute
CHECK (sched.holdsGroomingToken (myself)); // Side-Effect: acquired the Grooming-Token
CHECK (sched.decideDispatchNow (t1, now)); // also works if Grooming-Token is already acquired
CHECK (sched.holdsGroomingToken (myself));
CHECK (sched.decideDispatchNow (t1, now));
CHECK (sched.decideDispatchNow (t2, now)); // Boundary case time == now => good to execute
CHECK (sched.holdsGroomingToken (myself));
CHECK (sched.decideDispatchNow (t2, now));
CHECK (sched.holdsGroomingToken (myself));
CHECK (not sched.decideDispatchNow (t3, now));
CHECK (sched.holdsGroomingToken (myself));
CHECK (not sched.decideDispatchNow (t3, now)); // Task in the future shall not be dispatched now
CHECK (sched.holdsGroomingToken (myself)); // ...and this case has no impact on the Grooming-Token
sched.dropGroomingToken();
CHECK (not sched.decideDispatchNow (t3, now));
@ -260,7 +276,7 @@ namespace test {
blockGroomingToken(sched);
CHECK (not sched.acquireGoomingToken());
CHECK (not sched.decideDispatchNow (t1, now));
CHECK (not sched.decideDispatchNow (t1, now)); // unable to acquire => can not decide positively
CHECK (not sched.holdsGroomingToken (myself));
CHECK (not sched.decideDispatchNow (t2, now));
@ -275,7 +291,6 @@ namespace test {
/** @test verify logic of queue updates and work prioritisation.
* @todo WIP 10/23 define implement
*/
void
verify_findWork()
@ -295,7 +310,7 @@ namespace test {
Activity a3{3u,3u};
queue.instruct (a3, t3); // activity scheduled into the future
CHECK (not sched.findWork (queue, now)); // for time `now` not found
CHECK (not sched.findWork (queue, now)); // ... not found with time `now`
CHECK (t3 == queue.headTime());
queue.instruct (a1, t1);
@ -333,12 +348,11 @@ namespace test {
/** @test verify entrance point for performing an Activity chain.
* @todo WIP 10/23 define implement
*/
void
verify_postDispatch()
{
// rigged execution environment to detect activations
// rigged execution environment to detect activations--------------
ActivityDetector detector;
Activity& activity = detector.buildActivationProbe ("testActivity");
@ -388,12 +402,12 @@ namespace test {
CHECK (not sched.holdsGroomingToken (myself));
CHECK (not queue.peekHead()); // was enqueued, not executed
// Note: this test achieved a single direct invocation;
// Note: this test achieved one single direct invocation;
// all further cases after Seq-point-1 were queued only
CHECK (detector.ensureNoInvocation("testActivity")
.afterSeqIncrement(1));
// As sanity-check: after the point where we purged the queue
// As sanity-check: after the point where we purged the queue,
// two further cases where enqueued; we could retrieve them if
// re-acquiring the GroomingToken and using suitable query-time
unblockGroomingToken();
@ -417,7 +431,8 @@ namespace test {
* - Step-1 : schedule the Activity-term
* - Step-2 : later search for work, retrieve and dispatch the term
* - verify the expected sequence of Activities actually occurred
* @todo WIP 10/23 define implement
* @see ActivityLang::buildCalculationJob()
* @see ActivityDetector::buildMockJob()
*/
void
integratedWorkCycle()
@ -463,7 +478,7 @@ namespace test {
// ===================================================================== actual test sequence
// Add the Activity-Term to be scheduled at start-Time
// Add the Activity-Term to be scheduled for planned start-Time
sched.postDispatch (&anchor, start, detector.executionCtx, queue);
CHECK (detector.ensureNoInvocation("testJob"));
CHECK (not sched.holdsGroomingToken (myself));
@ -476,7 +491,7 @@ namespace test {
// Assuming a worker runs "later" and retrieves work...
Activity* act = sched.findWork(queue,now);
CHECK (sched.holdsGroomingToken (myself)); // acquired the GroomingToken
CHECK (isSameObject(*act, anchor)); // "found" the rigged Activity as next work to do
CHECK (isSameObject(*act, anchor)); // "found" the rigged Activity as next piece of work
sched.postDispatch (act, now, detector.executionCtx, queue);

View file

@ -80424,7 +80424,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="info"/>
<node CREATED="1690741912719" ID="ID_1973238180" MODIFIED="1690741925084" TEXT="ein Status/Steuerflag"/>
<node CREATED="1690741926157" ID="ID_1658082854" MODIFIED="1690741927768" TEXT="F&#xe4;lle">
<node CREATED="1690741929054" ID="ID_1938875580" MODIFIED="1690742050594" TEXT="PASS">
<node COLOR="#435e98" CREATED="1690741929054" ID="ID_1938875580" MODIFIED="1697664293261" TEXT="PASS">
<richcontent TYPE="NOTE"><html>
<head/
<body>
@ -80434,7 +80434,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
</node>
<node CREATED="1690742161893" ID="ID_1861458943" MODIFIED="1690742315028" TEXT="SKIP">
<node COLOR="#435e98" CREATED="1690742161893" ID="ID_1861458943" MODIFIED="1697664293262" TEXT="SKIP">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -80444,6 +80444,16 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
</node>
<node COLOR="#435e98" CREATED="1697664265466" ID="ID_38157517" MODIFIED="1697664293262" TEXT="WAIT">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
nothing to do; wait and re-check for work later
</p>
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1690742164165" ID="ID_1609304132" MODIFIED="1690742708723" TEXT="KILL">
<richcontent TYPE="NOTE"><html>
<head/>
@ -80801,9 +80811,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1680564304940" ID="ID_1657236591" MODIFIED="1680565125463" TEXT="Scheduler entwerfen">
<linktarget COLOR="#f6e1c2" DESTINATION="ID_1657236591" ENDARROW="Default" ENDINCLINATION="-1219;85;" ID="Arrow_ID_49470357" SOURCE="ID_59027079" STARTARROW="None" STARTINCLINATION="-2189;368;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1680564304940" ID="ID_1657236591" MODIFIED="1697664155547" TEXT="Scheduler entwerfen">
<linktarget COLOR="#f6e1c2" DESTINATION="ID_1657236591" ENDARROW="Default" ENDINCLINATION="-1219;87;" ID="Arrow_ID_49470357" SOURCE="ID_59027079" STARTARROW="None" STARTINCLINATION="-2189;368;"/>
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1687471254704" ID="ID_1902396309" MODIFIED="1687471266974" TEXT="Basis und Rahmen">
<icon BUILTIN="pencil"/>
<node CREATED="1687475603990" ID="ID_363400970" MODIFIED="1687475621515" TEXT="Subsystem: Engine">
@ -81598,8 +81608,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node CREATED="1680565469342" ID="ID_250843894" MODIFIED="1680566937368" TEXT="Priority-Scheduling">
<node CREATED="1680565469342" ID="ID_250843894" MODIFIED="1697664168767" TEXT="Priority-Scheduling">
<linktarget COLOR="#fec499" DESTINATION="ID_250843894" ENDARROW="Default" ENDINCLINATION="-644;84;" ID="Arrow_ID_1702721830" SOURCE="ID_12567096" STARTARROW="None" STARTINCLINATION="-233;30;"/>
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1684973294743" ID="ID_495348423" MODIFIED="1684973356775" TEXT="Strukturen und Repr&#xe4;sentation">
<arrowlink COLOR="#fe6d01" DESTINATION="ID_1599285907" ENDARROW="Default" ENDINCLINATION="-183;0;" ID="Arrow_ID_1756942771" STARTARROW="None" STARTINCLINATION="-502;-42;"/>
<icon BUILTIN="flag-yellow"/>
@ -81643,25 +81654,33 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689170049231" ID="ID_1688483414" MODIFIED="1689171254550" TEXT="Threadpool">
<arrowlink COLOR="#694db0" DESTINATION="ID_196314311" ENDARROW="Default" ENDINCLINATION="-56;-43;" ID="Arrow_ID_814147501" STARTARROW="None" STARTINCLINATION="-394;72;"/>
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1689170049231" ID="ID_1688483414" MODIFIED="1697675215197" TEXT="WorkForce (passiver Woker-Pool)">
<arrowlink COLOR="#4d82b0" DESTINATION="ID_196314311" ENDARROW="Default" ENDINCLINATION="-56;-43;" ID="Arrow_ID_814147501" STARTARROW="None" STARTINCLINATION="-440;34;"/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1693171997528" ID="ID_862845398" MODIFIED="1693172169618" TEXT="Komponenten aufbauen">
<linktarget COLOR="#87584c" DESTINATION="ID_862845398" ENDARROW="Default" ENDINCLINATION="-1041;0;" ID="Arrow_ID_735728098" SOURCE="ID_204159198" STARTARROW="None" STARTINCLINATION="-238;-282;"/>
<icon BUILTIN="pencil"/>
<node CREATED="1693172095351" ID="ID_605062962" MODIFIED="1693172311344" TEXT="Scheduler">
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1693172095351" ID="ID_605062962" MODIFIED="1697675312416" TEXT="Scheduler">
<icon BUILTIN="flag-pink"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1693172098402" ID="ID_671792975" MODIFIED="1697553002393" TEXT="Dependency-Injection">
<icon BUILTIN="help"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1693841227130" ID="ID_1537960830" MODIFIED="1693841284055" TEXT="WorkForce einbinden">
<arrowlink COLOR="#397cb2" DESTINATION="ID_987966047" ENDARROW="Default" ENDINCLINATION="-1039;-52;" ID="Arrow_ID_818972822" STARTARROW="None" STARTINCLINATION="-609;73;"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1693841227130" ID="ID_1537960830" MODIFIED="1697675265270" TEXT="WorkForce einbinden">
<arrowlink COLOR="#397cb2" DESTINATION="ID_987966047" ENDARROW="Default" ENDINCLINATION="-962;-41;" ID="Arrow_ID_818972822" STARTARROW="None" STARTINCLINATION="-609;73;"/>
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697675135117" ID="ID_880133050" MODIFIED="1697675148836" TEXT="ActivityLang + BlockFlow">
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1693172069235" ID="ID_1573845677" MODIFIED="1693172084048" TEXT="Layer-1: SchedulerInvocation"/>
<node CREATED="1693172074855" ID="ID_101356551" MODIFIED="1693172090591" TEXT="Layer-2: SchedulerCommutator"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1697663918107" ID="ID_210862409" MODIFIED="1697675123151" TEXT="Load-Controller vorsehen">
<linktarget COLOR="#75769b" DESTINATION="ID_210862409" ENDARROW="Default" ENDINCLINATION="-667;72;" ID="Arrow_ID_1800712901" SOURCE="ID_464175339" STARTARROW="None" STARTINCLINATION="-540;37;"/>
<icon BUILTIN="flag-pink"/>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1693172069235" ID="ID_1573845677" MODIFIED="1697675305351" TEXT="Layer-1: SchedulerInvocation"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1693172074855" ID="ID_101356551" MODIFIED="1697675305350" TEXT="Layer-2: SchedulerCommutator"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1687737433506" ID="ID_1608121280" MODIFIED="1687737442698" TEXT="einfacher Activity-Transport">
@ -81684,8 +81703,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node CREATED="1687737451105" ID="ID_925616893" MODIFIED="1687737457699" TEXT="Basis-Operationen">
<node COLOR="#338800" CREATED="1687737459167" ID="ID_1982661220" MODIFIED="1697509756856" TEXT="instruct">
<node COLOR="#338800" CREATED="1687737451105" ID="ID_925616893" MODIFIED="1697664109631" TEXT="Basis-Operationen">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1687737459167" FOLDED="true" ID="ID_1982661220" MODIFIED="1697509756856" TEXT="instruct">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1687737917521" ID="ID_1306162732" MODIFIED="1697509754333" TEXT="water-level definieren">
<icon BUILTIN="button_ok"/>
@ -81758,7 +81778,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="yes"/>
</node>
</node>
<node COLOR="#338800" CREATED="1687825916348" ID="ID_254177626" MODIFIED="1687826402411" TEXT="feedPrioritisation">
<node COLOR="#338800" CREATED="1687825916348" FOLDED="true" ID="ID_254177626" MODIFIED="1687826402411" TEXT="feedPrioritisation">
<linktarget COLOR="#31c960" DESTINATION="ID_254177626" ENDARROW="Default" ENDINCLINATION="169;9;" ID="Arrow_ID_1506119350" SOURCE="ID_167939453" STARTARROW="None" STARTINCLINATION="-2;9;"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1697474990041" HGAP="39" ID="ID_1899510010" MODIFIED="1697483151657" TEXT="wie wird der Bypass der Instruct-Queue realisiert?" VSHIFT="39">
@ -81829,8 +81849,16 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="yes"/>
</node>
</node>
<node COLOR="#338800" CREATED="1697664035780" ID="ID_12688296" MODIFIED="1697664105789" TEXT="Informationsfunktionen">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1697664042816" ID="ID_1946435661" MODIFIED="1697664117691" TEXT="empty()"/>
<node COLOR="#435e98" CREATED="1697664094137" ID="ID_1470365236" MODIFIED="1697664117692" TEXT="isDue(now)"/>
<node COLOR="#435e98" CREATED="1697664050047" ID="ID_762628611" MODIFIED="1697664117692" TEXT="headTime()"/>
<node COLOR="#435e98" CREATED="1697664060613" ID="ID_980495178" MODIFIED="1697664117691" TEXT="peekHead()"/>
</node>
<node CREATED="1687789568770" ID="ID_1189205980" MODIFIED="1687789575453" TEXT="Iterations-Schnittstelle">
</node>
<node COLOR="#338800" CREATED="1687789568770" FOLDED="true" ID="ID_1189205980" MODIFIED="1697664015525" TEXT="Iterations-Schnittstelle">
<icon BUILTIN="button_ok"/>
<node CREATED="1687789602339" ID="ID_1200625458" MODIFIED="1687789718505" TEXT="Zugang zum Head"/>
<node CREATED="1687789719097" ID="ID_908739206" MODIFIED="1687789773087" TEXT="Inkrement konsumiert Head"/>
<node COLOR="#435e98" CREATED="1687790434754" ID="ID_792756614" MODIFIED="1687790579147" TEXT="sind Iteratoren nicht zu aufwendig?">
@ -81885,12 +81913,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1689170064181" HGAP="5" ID="ID_987966047" MODIFIED="1697427690899" TEXT="WorkForce zur Ausf&#xfc;hrung" VSHIFT="7">
<linktarget COLOR="#397cb2" DESTINATION="ID_987966047" ENDARROW="Default" ENDINCLINATION="-1039;-52;" ID="Arrow_ID_818972822" SOURCE="ID_1537960830" STARTARROW="None" STARTINCLINATION="-609;73;"/>
<node COLOR="#338800" CREATED="1689170064181" FOLDED="true" HGAP="5" ID="ID_987966047" MODIFIED="1697427690899" TEXT="WorkForce zur Ausf&#xfc;hrung" VSHIFT="7">
<linktarget COLOR="#397cb2" DESTINATION="ID_987966047" ENDARROW="Default" ENDINCLINATION="-962;-41;" ID="Arrow_ID_818972822" SOURCE="ID_1537960830" STARTARROW="None" STARTINCLINATION="-609;73;"/>
<linktarget COLOR="#3974b2" DESTINATION="ID_987966047" ENDARROW="Default" ENDINCLINATION="-1039;-52;" ID="Arrow_ID_7965989" SOURCE="ID_1957090536" STARTARROW="None" STARTINCLINATION="-1231;87;"/>
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1689170081403" ID="ID_196314311" MODIFIED="1697427465994" TEXT="Technologie-Entscheidung">
<linktarget COLOR="#694db0" DESTINATION="ID_196314311" ENDARROW="Default" ENDINCLINATION="-56;-43;" ID="Arrow_ID_814147501" SOURCE="ID_1688483414" STARTARROW="None" STARTINCLINATION="-394;72;"/>
<linktarget COLOR="#4d82b0" DESTINATION="ID_196314311" ENDARROW="Default" ENDINCLINATION="-56;-43;" ID="Arrow_ID_814147501" SOURCE="ID_1688483414" STARTARROW="None" STARTINCLINATION="-440;34;"/>
<linktarget COLOR="#b22e63" DESTINATION="ID_196314311" ENDARROW="Default" ENDINCLINATION="-1383;-51;" ID="Arrow_ID_134934445" SOURCE="ID_14638704" STARTARROW="None" STARTINCLINATION="-753;40;"/>
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
@ -84359,23 +84387,25 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1693792157926" ID="ID_429801566" MODIFIED="1693792193345" TEXT="komplett heruntergeregelt &#x27f9; Render-Engine deaktiviert"/>
<node CREATED="1693792250942" ID="ID_1000686206" MODIFIED="1693792285653" TEXT="Obergrenze &#x2259; Hardware-concurrency * Provisionierungs-Faktor"/>
<node CREATED="1693792308542" ID="ID_1678880734" MODIFIED="1693792318777" TEXT="Herunterregeln erfolgt kooperativ"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1693792585515" ID="ID_464175339" MODIFIED="1693792605896" TEXT="geplant: dynamische Kapazit&#xe4;tsregelung">
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1693792585515" FOLDED="true" ID="ID_464175339" MODIFIED="1693792605896" TEXT="geplant: dynamische Kapazit&#xe4;tsregelung">
<arrowlink COLOR="#75769b" DESTINATION="ID_210862409" ENDARROW="Default" ENDINCLINATION="-667;72;" ID="Arrow_ID_1800712901" STARTARROW="None" STARTINCLINATION="-540;37;"/>
<icon BUILTIN="hourglass"/>
<node CREATED="1693792629986" ID="ID_1269240792" MODIFIED="1693792648043" TEXT="nur mindest-St&#xe4;rke l&#xe4;uft"/>
<node CREATED="1693792648648" ID="ID_1347574580" MODIFIED="1693792689438" TEXT="bei Bedarf wird hochsakliert"/>
</node>
</node>
<node CREATED="1693792477807" ID="ID_5065581" MODIFIED="1693792530740" TEXT="Zyklus: pull work / check / sleep">
<node CREATED="1693792715966" ID="ID_717442289" MODIFIED="1693792730000" TEXT="die &quot;pull-work&quot;-Funkton wird vom Scheduler-Layer-2 bereitgestellt"/>
<node CREATED="1693792715966" ID="ID_717442289" MODIFIED="1697663859531" TEXT="die &quot;pull-work&quot;-Funkton wird vom Scheduler-Service bereitgestellt"/>
<node CREATED="1697663861416" ID="ID_558783590" MODIFIED="1697663878469" TEXT="...ist aber implementiert mit Funktionalit&#xe4;t von Layer-2"/>
<node CREATED="1693792744114" ID="ID_1037530409" MODIFIED="1693792754452" TEXT="die Schlaf-Periode ist ein (steuer)-Parameter"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1693792760213" ID="ID_1223151647" MODIFIED="1694304517016" TEXT="ggfs leicht randomisiert">
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1693792760213" FOLDED="true" ID="ID_1223151647" MODIFIED="1694304517016" TEXT="ggfs leicht randomisiert">
<icon BUILTIN="hourglass"/>
<node CREATED="1693792791729" ID="ID_649360495" MODIFIED="1693792804966" TEXT="Einsch&#xe4;tzung: das gen&#xfc;gt um Contention zu vermeiden"/>
<node CREATED="1693792900758" ID="ID_1613781033" MODIFIED="1693792927222" TEXT="Vorraussetzung: Arbeitsphase &gt;&gt; Management-Phase"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1693952215256" ID="ID_532083956" MODIFIED="1694304448282" TEXT="Implementierung">
<node COLOR="#338800" CREATED="1693952215256" FOLDED="true" ID="ID_532083956" MODIFIED="1694304448282" TEXT="Implementierung">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1693952247831" ID="ID_1732680738" LINK="#ID_391262141" MODIFIED="1694096132122" TEXT="Work-Function m&#xf6;glichst inline aber statisch konfigurierbar">
<richcontent TYPE="NOTE"><html>
@ -84852,8 +84882,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node CREATED="1680565476652" ID="ID_1218283238" MODIFIED="1684973201854" TEXT="Dependency-Notification">
<linktarget COLOR="#fec499" DESTINATION="ID_1218283238" ENDARROW="Default" ENDINCLINATION="-664;74;" ID="Arrow_ID_443600884" SOURCE="ID_695181807" STARTARROW="None" STARTINCLINATION="-240;29;"/>
<node CREATED="1680565476652" ID="ID_1218283238" MODIFIED="1697664175912" TEXT="Dependency-Notification">
<linktarget COLOR="#fec499" DESTINATION="ID_1218283238" ENDARROW="Default" ENDINCLINATION="-678;64;" ID="Arrow_ID_443600884" SOURCE="ID_695181807" STARTARROW="None" STARTINCLINATION="-240;29;"/>
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<node CREATED="1685029743471" ID="ID_662250285" MODIFIED="1685029748808" TEXT="Benachrichtigungen">
<node COLOR="#435e98" CREATED="1685029752445" ID="ID_1073371022" MODIFIED="1697642160212" TEXT="wohin? andere Threads &#x27f9; lock-free Messaging-Queue">
<icon BUILTIN="help"/>
@ -84882,9 +84913,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1685030153172" ID="ID_1240235053" MODIFIED="1685030161822" TEXT="Zeit-Messungen">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1697675093651" ID="ID_947560626" MODIFIED="1697675099905" TEXT="IO-Callbacks">
<icon BUILTIN="hourglass"/>
</node>
</node>
<node COLOR="#338800" CREATED="1687909561193" ID="ID_1235436372" MODIFIED="1697585733751" TEXT="GroomingToken">
</node>
<node COLOR="#338800" CREATED="1687909561193" FOLDED="true" ID="ID_1235436372" MODIFIED="1697585733751" TEXT="GroomingToken">
<icon BUILTIN="button_ok"/>
<node CREATED="1687909742256" ID="ID_768602373" MODIFIED="1687909749803" TEXT="implementiert per atomic CAS"/>
<node CREATED="1687909758046" ID="ID_1061447302" MODIFIED="1687909764595" TEXT="nur ein Worker kann es jeweils besitzen"/>
@ -85003,7 +85037,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node COLOR="#338800" CREATED="1697475170816" HGAP="36" ID="ID_1920465683" MODIFIED="1697642019595" TEXT="API festlegen" VSHIFT="7">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1697475184438" ID="ID_140675790" MODIFIED="1697641966678" TEXT="bisher treten zwei verschiedene Perspektiven auf">
<node COLOR="#435e98" CREATED="1697475184438" FOLDED="true" ID="ID_140675790" MODIFIED="1697641966678" TEXT="bisher treten zwei verschiedene Perspektiven auf">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1697475204580" ID="ID_17372466" MODIFIED="1697475216748" TEXT="Layer-2 als Ausf&#xfc;hrungs-Kette">
<node CREATED="1697482695414" ID="ID_1741555904" MODIFIED="1697482816448" TEXT="und zwar insofern stets einige Schritte strukturiert vollzogen werden m&#xfc;ssen">
@ -85034,7 +85068,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1697553250983" ID="ID_438556046" MODIFIED="1697594581615" TEXT="doWork &#x27fc; findWork">
<node COLOR="#338800" CREATED="1697553250983" FOLDED="true" ID="ID_438556046" MODIFIED="1697594581615" TEXT="doWork &#x27fc; findWork">
<linktarget COLOR="#7b8795" DESTINATION="ID_438556046" ENDARROW="Default" ENDINCLINATION="28;-22;" ID="Arrow_ID_520978128" SOURCE="ID_1600142035" STARTARROW="None" STARTINCLINATION="-463;26;"/>
<linktarget COLOR="#718daf" DESTINATION="ID_438556046" ENDARROW="Default" ENDINCLINATION="-261;714;" ID="Arrow_ID_1821254034" SOURCE="ID_1076701414" STARTARROW="None" STARTINCLINATION="372;24;"/>
<icon BUILTIN="button_ok"/>
@ -85066,7 +85100,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1697553556862" ID="ID_239855477" MODIFIED="1697641958566" TEXT="PostDispatch">
<node COLOR="#338800" CREATED="1697553556862" FOLDED="true" ID="ID_239855477" MODIFIED="1697641958566" TEXT="PostDispatch">
<icon BUILTIN="button_ok"/>
<node CREATED="1697553564965" ID="ID_280879756" MODIFIED="1697553576815" TEXT="der &#xbb;POST-Eingang&#xab;">
<icon BUILTIN="ksmiletris"/>
@ -85176,7 +85210,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1697553674095" ID="ID_1453351337" MODIFIED="1697594493393" TEXT="decideDispatchNow">
<node COLOR="#338800" CREATED="1697553674095" FOLDED="true" ID="ID_1453351337" MODIFIED="1697594493393" TEXT="decideDispatchNow">
<linktarget COLOR="#6d677a" DESTINATION="ID_1453351337" ENDARROW="Default" ENDINCLINATION="3;-38;" ID="Arrow_ID_1868115325" SOURCE="ID_937487663" STARTARROW="None" STARTINCLINATION="-51;3;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1697579158340" ID="ID_793480355" MODIFIED="1697579176584" TEXT="Ausf&#xfc;hren ist m&#xf6;glich...">
@ -85245,7 +85279,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="messagebox_warning"/>
</node>
</node>
<node COLOR="#338800" CREATED="1697559873907" ID="ID_409935766" MODIFIED="1697567713362" TEXT="acquireGoomingToken">
<node COLOR="#338800" CREATED="1697559873907" FOLDED="true" ID="ID_409935766" MODIFIED="1697567713362" TEXT="acquireGoomingToken">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1697560125437" ID="ID_129201087" MODIFIED="1697567708667" TEXT="implementiert als Compare-and-Swap">
<icon BUILTIN="button_ok"/>
@ -85260,7 +85294,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1697567746057" ID="ID_193744284" MODIFIED="1697567749561" TEXT="alles andere: relaxed"/>
</node>
</node>
<node COLOR="#338800" CREATED="1697559880222" ID="ID_1458427038" MODIFIED="1697567772880" TEXT="dropGroomingToken">
<node COLOR="#338800" CREATED="1697559880222" FOLDED="true" ID="ID_1458427038" MODIFIED="1697567772880" TEXT="dropGroomingToken">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1697560157372" ID="ID_1167908140" MODIFIED="1697567753440" TEXT="Konsiistenzpr&#xfc;fung nur als Assertion">
<icon BUILTIN="button_ok"/>
@ -85269,7 +85303,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1697559931219" ID="ID_199319740" MODIFIED="1697567772039" TEXT="holdsGroomingToken">
<node COLOR="#338800" CREATED="1697559931219" FOLDED="true" ID="ID_199319740" MODIFIED="1697567772039" TEXT="holdsGroomingToken">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1697560065912" ID="ID_1054899813" MODIFIED="1697567766331" TEXT="zur besseren Lesbarkeit: Thread-ID als Argument">
<icon BUILTIN="button_ok"/>
@ -85279,9 +85313,13 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node CREATED="1687788623248" ID="ID_1335631068" MODIFIED="1687788627335" TEXT="Ausf&#xfc;hrungs-Struktur">
<node CREATED="1685029833448" ID="ID_1405359337" MODIFIED="1685029836621" TEXT="Verzweigungen">
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1685029839057" ID="ID_1926570028" MODIFIED="1685029854988" TEXT="verzweigte Ausf&#xfc;hrungs-Strukur oder nur Entscheidungs-Struktur?">
<node COLOR="#435e98" CREATED="1687788623248" ID="ID_1335631068" MODIFIED="1697663767821" TEXT="Ausf&#xfc;hrungs-Struktur">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="info"/>
<icon BUILTIN="forward"/>
<node CREATED="1685029833448" ID="ID_1405359337" MODIFIED="1697663684686" TEXT="Verzweigungen">
<icon BUILTIN="edit"/>
<node COLOR="#435e98" CREATED="1685029839057" ID="ID_1926570028" MODIFIED="1697663503176" TEXT="verzweigte Ausf&#xfc;hrungs-Strukur oder nur Entscheidungs-Struktur?">
<icon BUILTIN="help"/>
<node CREATED="1687823249714" ID="ID_1864655181" MODIFIED="1687825736511">
<richcontent TYPE="NODE"><html>
@ -85294,18 +85332,50 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1687823355712" ID="ID_1307602651" MODIFIED="1687823376918" TEXT="Welche Entscheidungs-Strukturen k&#xf6;nnten in der Queue stattfinden?">
<node COLOR="#435e98" CREATED="1687823355712" ID="ID_1307602651" MODIFIED="1697663050658" TEXT="Welche Entscheidungs-Strukturen k&#xf6;nnten in der Queue stattfinden?">
<icon BUILTIN="help"/>
<node CREATED="1687823967742" ID="ID_854344895" MODIFIED="1687823989409" TEXT="eine Pr&#xfc;fung regelm&#xe4;&#xdf;ig wiederholen"/>
<node CREATED="1687824048509" ID="ID_713697923" MODIFIED="1687824058560" TEXT="bei Erfolg einen anderen Term einf&#xfc;gen"/>
<node CREATED="1687824086888" ID="ID_1796701768" MODIFIED="1687824103613" TEXT="oder einen anderen Term deaktivieren (=l&#xf6;schen)"/>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1697663035748" ID="ID_587933220" MODIFIED="1697663048429" TEXT="alle diese brauchen wir im Moment nicht">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1687824184209" ID="ID_1244600209" MODIFIED="1687825709638" TEXT="Event-getriebene Entscheidungs-Strukturen...?">
</node>
<node COLOR="#435e98" CREATED="1687824184209" ID="ID_1244600209" MODIFIED="1697663170611" TEXT="Event-getriebene Entscheidungs-Strukturen...?">
<icon BUILTIN="help"/>
<node CREATED="1687824217830" ID="ID_290545800" MODIFIED="1687824234977" TEXT="nach dem Ende eines Job wird noch ein Activity-Term abgefeuert"/>
<node CREATED="1687824273791" ID="ID_143043563" MODIFIED="1687824299591" TEXT="ein Term ist mit einem externen Signal verbunden"/>
<node CREATED="1687824301438" ID="ID_1540430139" MODIFIED="1687824323069" TEXT="...und das Signal f&#xfc;hrt dann zum Abfeuern eines weiteren Terms"/>
<node CREATED="1687825665315" ID="ID_402640209" MODIFIED="1687825688256">
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1687824301438" ID="ID_1540430139" MODIFIED="1697663168402" TEXT="...und das Signal f&#xfc;hrt dann zum Abfeuern eines weiteren Terms">
<icon BUILTIN="hourglass"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1697663172758" ID="ID_391965463" MODIFIED="1697663305946" TEXT="das mu&#xdf; noch implementiert werden">
<icon BUILTIN="bell"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1697663178362" ID="ID_961906452" MODIFIED="1697663472236" TEXT="h&#xe4;ngt stark von den IO-Callback-M&#xf6;glichkeiten ab">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Bisher wurde asynchrones IO nur als theoretische M&#246;glichkeit betrachtet, aber noch nicht im Detail untersucht &#8212; im Besonderen die M&#246;glichkeiten von IO_URING werden relevant sein
</p>
<ul>
<li>
wie werden dort Callbacks eingerichtet und von wem aufgerufen?
</li>
<li>
welche custom-Payload kann mitgegeben werden?
</li>
</ul>
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1697663253711" ID="ID_514916866" MODIFIED="1697663294035" TEXT="zu L&#xf6;sen">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1697663214829" ID="ID_481503607" MODIFIED="1697663265466" TEXT="Callback mu&#xdf; an die richtige Stelle zur&#xfc;ckfinden"/>
<node CREATED="1697663266078" ID="ID_1713481807" MODIFIED="1697663288631" TEXT="Anbindung an das BlockFlow-Epochen-Gate"/>
</node>
</node>
<node CREATED="1687825665315" HGAP="22" ID="ID_402640209" MODIFIED="1697663496299" STYLE="bubble">
<richcontent TYPE="NODE"><html>
<head/>
<body>
@ -85314,17 +85384,23 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<edge COLOR="#fb2d2d"/>
<icon BUILTIN="forward"/>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#392a6e" CREATED="1697663080415" ID="ID_1219177820" MODIFIED="1697663146705" TEXT="Verdrahtungs-M&#xf6;glichkeiten der Ausf&#xfc;hrungs-Struktur gen&#xfc;gen vorerst">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685029859862" ID="ID_60316038" MODIFIED="1685029875094" TEXT="Pr&#xe4;dikat: Auswertung im Engine-Kontext">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1685029859862" ID="ID_60316038" MODIFIED="1697663520262" TEXT="Pr&#xe4;dikat: Auswertung im Engine-Kontext">
<icon BUILTIN="hourglass"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1685029878060" ID="ID_526042153" MODIFIED="1685029885075" TEXT="was hei&#xdf;t das?">
<icon BUILTIN="help"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1692370072446" ID="ID_561777955" MODIFIED="1692370080979" TEXT="vorerst wohl gar nicht notwendig">
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1692370072446" ID="ID_561777955" MODIFIED="1697663528091" TEXT="vorerst wohl gar nicht notwendig">
<icon BUILTIN="hourglass"/>
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685029907272" ID="ID_1507342460" MODIFIED="1685029927215" TEXT="Folge &#x27f9; inhibit Activity">
@ -85340,9 +85416,24 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<arrowlink COLOR="#653694" DESTINATION="ID_424129996" ENDARROW="Default" ENDINCLINATION="-196;-12;" ID="Arrow_ID_609240876" STARTARROW="None" STARTINCLINATION="367;18;"/>
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1697674985089" ID="ID_927248825" MODIFIED="1697675053015">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
derzeit gen&#252;gt der Deadline-Check von <font face="Monospaced" color="#595959">Activity::</font><font face="Monospaced" color="#753915"><b>GATE</b></font>
</p>
</body>
</html></richcontent>
<icon BUILTIN="info"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1697674976374" ID="ID_1822149494" MODIFIED="1697675020413" TEXT="Weiterungen noch nicht absehbar">
<icon BUILTIN="hourglass"/>
</node>
</node>
<node CREATED="1687788654684" ID="ID_1528240185" MODIFIED="1687788658716" TEXT="Terme">
</node>
<node CREATED="1687788654684" ID="ID_1528240185" MODIFIED="1697664210343" TEXT="Activity-Terme">
<icon BUILTIN="edit"/>
<node CREATED="1687788659433" ID="ID_1507624704" MODIFIED="1687788784350" TEXT="es werden Satz-artige Terme ausgewertet">
<icon BUILTIN="yes"/>
<node CREATED="1690492542473" ID="ID_508740677" MODIFIED="1690492555436" TEXT="die Auswertung implementiert direkt die Abh&#xe4;ngigkeits-Struktur"/>
@ -86144,7 +86235,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1688336761542" ID="ID_145928010" MODIFIED="1697509851855" TEXT="SchedulerInvocation_test">
<node COLOR="#338800" CREATED="1688336761542" FOLDED="true" ID="ID_145928010" MODIFIED="1697509851855" TEXT="SchedulerInvocation_test">
<icon BUILTIN="button_ok"/>
<node CREATED="1688337123318" ID="ID_1686181795" MODIFIED="1688337233916" TEXT="&#xbb;Layer-1&#xab; : Queue operation">
<icon BUILTIN="info"/>
@ -86180,8 +86271,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1688336794355" ID="ID_1705923970" MODIFIED="1697662668390" TEXT="SchedulerCommutator_test">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1688336794355" FOLDED="true" ID="ID_1705923970" MODIFIED="1697674916927" TEXT="SchedulerCommutator_test">
<icon BUILTIN="button_ok"/>
<node CREATED="1688337141875" ID="ID_1442397948" MODIFIED="1697552361129" TEXT="&#xbb;Layer-2&#xab; : Activity execution">
<icon BUILTIN="info"/>
</node>
@ -86295,10 +86386,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
<node COLOR="#435e98" CREATED="1697560612176" ID="ID_1970152549" MODIFIED="1697662384898" TEXT="F&#xe4;lle">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1697560628310" ID="ID_670606112" MODIFIED="1697562328081" TEXT="demonstrateSimpleUsage">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1697560628310" ID="ID_670606112" MODIFIED="1697674910900" TEXT="demonstrateSimpleUsage">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1697560505486" ID="ID_1321080717" LINK="#ID_409935766" MODIFIED="1697571165841" TEXT="verify_GroomingToken">
<node COLOR="#338800" CREATED="1697560505486" FOLDED="true" 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"/>
@ -86328,7 +86419,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1697560511607" ID="ID_764686457" LINK="#ID_1453351337" MODIFIED="1697585897682" TEXT="verify_DispatchDecision">
<node COLOR="#338800" CREATED="1697560511607" FOLDED="true" ID="ID_764686457" LINK="#ID_1453351337" MODIFIED="1697585897682" TEXT="verify_DispatchDecision">
<icon BUILTIN="button_ok"/>
<node CREATED="1697590592976" ID="ID_404768054" MODIFIED="1697590611320" TEXT="brauche bequeme L&#xf6;sung um das GroomingToken zu blocken">
<icon BUILTIN="yes"/>
@ -86342,7 +86433,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1697560535930" ID="ID_849370574" LINK="#ID_438556046" MODIFIED="1697594486097" TEXT="verify_findWork">
<node COLOR="#338800" CREATED="1697560535930" FOLDED="true" ID="ID_849370574" LINK="#ID_438556046" MODIFIED="1697594486097" TEXT="verify_findWork">
<icon BUILTIN="button_ok"/>
<node CREATED="1697585964522" ID="ID_1835507068" MODIFIED="1697585970582" TEXT="Szenarien">
<icon BUILTIN="list"/>
@ -86359,7 +86450,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1697560546952" ID="ID_1326942653" MODIFIED="1697641948262" TEXT="verify_postDispatch">
<node COLOR="#338800" CREATED="1697560546952" FOLDED="true" ID="ID_1326942653" MODIFIED="1697641948262" TEXT="verify_postDispatch">
<icon BUILTIN="button_ok"/>
<node CREATED="1697630618833" ID="ID_1032090324" MODIFIED="1697630748734" TEXT="Szenarien">
<linktarget COLOR="#9ca0a6" DESTINATION="ID_1032090324" ENDARROW="Default" ENDINCLINATION="-719;-92;" ID="Arrow_ID_1412557043" SOURCE="ID_1337049621" STARTARROW="None" STARTINCLINATION="-335;509;"/>
@ -86385,23 +86476,20 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1697560591659" ID="ID_1581648425" MODIFIED="1697662380188" TEXT="integratedWorkCycle">
<node COLOR="#338800" CREATED="1697560591659" FOLDED="true" ID="ID_1581648425" MODIFIED="1697662380188" TEXT="integratedWorkCycle">
<icon BUILTIN="button_ok"/>
<node CREATED="1697643554969" ID="ID_136268123" MODIFIED="1697643896607" TEXT="Ma&#xdf;gabe">
<icon BUILTIN="yes"/>
<node CREATED="1697643566840" ID="ID_1881707348" MODIFIED="1697643573858" TEXT="Perspektive ist Layer-2"/>
<node CREATED="1697643574446" ID="ID_876825377" MODIFIED="1697643596396">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
aber <i>das ganze Geschehen </i>einmal durchspielen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1697643597068" ID="ID_336540433" MODIFIED="1697643621773" TEXT="...vom Planen eines Jobs bis zur Ausf&#xfc;hrung"/>
</node>
@ -86431,9 +86519,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node CREATED="1697643873588" ID="ID_1914496998" MODIFIED="1697644383309">
<richcontent TYPE="NODE"><html>
<head>
</head>
<head/>
<body>
<p>
Activity-Term pr&#228;parieren wie im <font face="Monospaced" color="#333333">SchedulerActivity_test::</font><font face="Monospaced" color="#020080"><b>scenario_RenderJob</b></font><font face="Monospaced" color="#333333">()</font>
@ -86454,9 +86540,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
<node CREATED="1697657638874" ID="ID_1235782778" MODIFIED="1697657728816" TEXT="auch daf&#xfc;r gibts bereits ein Beispiel">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<head/>
<body>
<p>
<font color="#333333" face="Monospaced">SchedulerActivity_test::</font><font color="#020080" face="Monospaced"><b>scenario_Notification</b></font><font color="#333333" face="Monospaced">()</font>
@ -95365,7 +95449,7 @@ class Something
<arrowlink COLOR="#f6e1c2" DESTINATION="ID_1180632123" ENDARROW="Default" ENDINCLINATION="-985;-61;" ID="Arrow_ID_1052251062" STARTARROW="None" STARTINCLINATION="-2243;270;"/>
</node>
<node BACKGROUND_COLOR="#e2ce95" COLOR="#ec6b17" CREATED="1654441361325" ID="ID_59027079" MODIFIED="1680565125463" STYLE="bubble" TEXT="Scheduler">
<arrowlink COLOR="#f6e1c2" DESTINATION="ID_1657236591" ENDARROW="Default" ENDINCLINATION="-1219;85;" ID="Arrow_ID_49470357" STARTARROW="None" STARTINCLINATION="-2189;368;"/>
<arrowlink COLOR="#f6e1c2" DESTINATION="ID_1657236591" ENDARROW="Default" ENDINCLINATION="-1219;87;" ID="Arrow_ID_49470357" STARTARROW="None" STARTINCLINATION="-2189;368;"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1679783158745" HGAP="36" ID="ID_25937632" MODIFIED="1679783197261" TEXT="Definition" VSHIFT="11">
@ -95776,7 +95860,7 @@ class Something
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1680561901447" ID="ID_695181807" MODIFIED="1689170140108" TEXT="Layer-2 : Notification">
<arrowlink COLOR="#fec499" DESTINATION="ID_1218283238" ENDARROW="Default" ENDINCLINATION="-664;74;" ID="Arrow_ID_443600884" STARTARROW="None" STARTINCLINATION="-240;29;"/>
<arrowlink COLOR="#fec499" DESTINATION="ID_1218283238" ENDARROW="Default" ENDINCLINATION="-678;64;" ID="Arrow_ID_443600884" STARTARROW="None" STARTINCLINATION="-240;29;"/>
<icon BUILTIN="pencil"/>
</node>
</node>