Scheduler-test: rework handling of notifications in the Activity-Language
While the recent refactoring...
206c67cc
...was a step into the right direction, it pushed too hard,
overlooking the requirement to protect the scheduler contents
and thus all of the Activity-chains against concurrent modification.
Moreover, the recent solution still seems not quite orthogonal.
Thus the handling of notifications was thoroughly reworked:
- the explicit "double-dispatch" was removed, since actual usage
of the language indicates that we only need notifications to
Gate (and Hook), but not to any other conceivable Activity.
- thus it seems unnecessary to turn "notification" into some kind
of secondary work mode. Rather, it is folded as special case
into the regular dispatch.
This leads to new processing rules:
- a POST goes into λ-post (obviously... that's its meaning)
- a NOTIFY now passes its *target* into λ-post
- λ-post invokes ''dispatch''
- and **dispatching a Gate now implies to notify the Gate**
This greatly simplifies the »state machine« in the Activity-Language,
but also incurs some limitations (which seems adequate, since it is
now clear that we do not ''schedule'' or ''dispatch'' arbitrary
Activities — rather we'll do this only with POST and NOTIFY,
and all further processing happens by passing activation
along the chain, without involving the Scheduler)
This commit is contained in:
parent
75b5eea2d3
commit
1cbb6b7371
8 changed files with 536 additions and 207 deletions
|
|
@ -107,8 +107,8 @@ namespace gear {
|
|||
+ util::toString(data_.timing.quality);
|
||||
case NOTIFY:
|
||||
return util::showAddr(data_.notification.target)
|
||||
+ ", report="
|
||||
+ util::toString(data_.notification.report);
|
||||
+ ", timing:"
|
||||
+ util::toString(Time{data_.notification.timing});
|
||||
case GATE:
|
||||
return "<"
|
||||
+ util::toString(data_.condition.rest)
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ namespace gear {
|
|||
REQUIRE (notificationSrc.is (Activity::NOTIFY));
|
||||
setupGate();
|
||||
gate_->incDependencies();
|
||||
notificationSrc.setNotificationTarget (gate_);
|
||||
notificationSrc.setNotificationTarget (gate_, Time{post_->data_.timeWindow.life});
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -186,6 +186,8 @@ namespace gear {
|
|||
, Time now
|
||||
, void* executionCtx) =0;
|
||||
|
||||
virtual Time getDeadline() const =0;
|
||||
|
||||
virtual std::string
|
||||
diagnostic() const
|
||||
{
|
||||
|
|
@ -204,8 +206,6 @@ namespace gear {
|
|||
* The Execution Context need to be passed to any Activity _activation;_
|
||||
* it provides the _bindings_ for functionality defined only on a conceptual
|
||||
* level, and provided by an opaque implementation (actually the Scheduler)
|
||||
* @remark `getWaitDelay` was once used for Gate, but is now an obscure
|
||||
* fall-back for _other notifications_ (retained for future use)
|
||||
*/
|
||||
template<class EXE>
|
||||
constexpr void
|
||||
|
|
@ -216,7 +216,6 @@ namespace gear {
|
|||
ASSERT_MEMBER_FUNCTOR (&EXE::done, void(Time, size_t));
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::tick, Proc(Time));
|
||||
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::getWaitDelay, Offset());
|
||||
ASSERT_MEMBER_FUNCTOR (&EXE::getSchedTime, Time());
|
||||
}
|
||||
|
||||
|
|
@ -291,6 +290,7 @@ namespace gear {
|
|||
bool isDead (Time now) const { return dead <= now;}
|
||||
bool isHold () const { return rest > 0; }
|
||||
bool isFree (Time now) const { return not (isHold() or isDead(now)); }
|
||||
Time getDeadline() const { return Time{dead}; }
|
||||
void incDependencies() { ++rest; }
|
||||
|
||||
Time
|
||||
|
|
@ -320,7 +320,7 @@ namespace gear {
|
|||
struct Notification
|
||||
{
|
||||
Activity* target;
|
||||
size_t report;
|
||||
Instant timing;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -367,10 +367,11 @@ namespace gear {
|
|||
}
|
||||
|
||||
explicit
|
||||
Activity (Activity* target) noexcept
|
||||
Activity (Activity* target, Time limitWhen =Time::ANYTIME) noexcept
|
||||
: Activity{NOTIFY}
|
||||
{
|
||||
data_.notification.target = target;
|
||||
data_.notification.timing = limitWhen;
|
||||
}
|
||||
|
||||
explicit
|
||||
|
|
@ -424,13 +425,10 @@ namespace gear {
|
|||
template<class EXE>
|
||||
activity::Proc dispatch (Time now, EXE& executionCtx);
|
||||
|
||||
template<class EXE>
|
||||
activity::Proc notify (Time now, EXE& executionCtx);
|
||||
|
||||
|
||||
/* === special case access and manipulation === */
|
||||
bool
|
||||
is (Activity::Verb expectedVerb)
|
||||
is (Activity::Verb expectedVerb) const
|
||||
{
|
||||
return expectedVerb == this->verb_;
|
||||
}
|
||||
|
|
@ -443,10 +441,11 @@ namespace gear {
|
|||
}
|
||||
|
||||
void
|
||||
setNotificationTarget (Activity* target)
|
||||
setNotificationTarget (Activity* target, Time limitStart =Time::ANYTIME)
|
||||
{
|
||||
REQUIRE (is (NOTIFY));
|
||||
data_.notification.target = target;
|
||||
data_.notification.timing = limitStart;
|
||||
}
|
||||
|
||||
Time
|
||||
|
|
@ -532,15 +531,6 @@ namespace gear {
|
|||
return activity::PASS;
|
||||
}
|
||||
|
||||
template<class EXE>
|
||||
activity::Proc
|
||||
notifyTarget (Time now, EXE& executionCtx)
|
||||
{
|
||||
REQUIRE (NOTIFY == verb_);
|
||||
REQUIRE (data_.notification.target);
|
||||
return data_.notification.target->notify (now, executionCtx);
|
||||
}
|
||||
|
||||
template<class EXE>
|
||||
activity::Proc
|
||||
checkGate (Time now, EXE&)
|
||||
|
|
@ -554,9 +544,8 @@ namespace gear {
|
|||
return activity::PASS;
|
||||
}
|
||||
|
||||
template<class EXE>
|
||||
activity::Proc
|
||||
receiveGateNotification (Time now, EXE& executionCtx)
|
||||
receiveGateNotification (Time now)
|
||||
{
|
||||
REQUIRE (GATE == verb_);
|
||||
if (data_.condition.rest > 0)
|
||||
|
|
@ -565,33 +554,39 @@ namespace gear {
|
|||
// maybe the Gate has been opened by this notification?
|
||||
if (data_.condition.isFree(now))
|
||||
{//yes => activate gated chain but lock redundant invocations
|
||||
Time dead = data_.condition.lockPermanently();
|
||||
return postChain (now,dead, executionCtx);
|
||||
data_.condition.lockPermanently();
|
||||
return activity::PASS;
|
||||
} }
|
||||
return activity::PASS;
|
||||
}
|
||||
|
||||
template<class EXE>
|
||||
activity::Proc
|
||||
dispatchSelf (Time when, Time dead, EXE& executionCtx)
|
||||
{
|
||||
return executionCtx.post (when, dead, this, executionCtx);
|
||||
}
|
||||
|
||||
template<class EXE>
|
||||
activity::Proc
|
||||
dispatchSelfDelayed (Time now, Time dead, EXE& executionCtx)
|
||||
{
|
||||
dispatchSelf (now + executionCtx.getWaitDelay(), dead, executionCtx);
|
||||
return activity::SKIP;
|
||||
}
|
||||
|
||||
template<class EXE>
|
||||
activity::Proc
|
||||
postChain (Time when, Time dead, EXE& executionCtx)
|
||||
postSelf (Time now, EXE& executionCtx)
|
||||
{
|
||||
REQUIRE (next);
|
||||
return executionCtx.post (when, dead, next, executionCtx);
|
||||
if (is(POST))
|
||||
return executionCtx.post (Time{data_.timeWindow.life},Time{data_.timeWindow.dead}, this, executionCtx);
|
||||
else
|
||||
return executionCtx.post (now,Time::NEVER, this, executionCtx);
|
||||
}
|
||||
|
||||
template<class EXE>
|
||||
activity::Proc
|
||||
postNotify (Time now, EXE& executionCtx)
|
||||
{
|
||||
REQUIRE (is(NOTIFY));
|
||||
Activity* target = data_.notification.target;
|
||||
REQUIRE (target);
|
||||
REQUIRE (not target->is(HOOK) or target->data_.callback.hook);
|
||||
Time startHint = target->is(GATE) or
|
||||
target->is(HOOK)? Time{data_.notification.timing}
|
||||
: now;
|
||||
Time deadline = target->is(GATE)? target->data_.condition.getDeadline()
|
||||
: target->is(HOOK)? target->data_.callback.hook->getDeadline()
|
||||
: Time::NEVER;
|
||||
// indirectly forward to Activity::dispatch()
|
||||
return executionCtx.post (startHint,deadline, target, executionCtx);
|
||||
}
|
||||
|
||||
template<class EXE>
|
||||
|
|
@ -650,11 +645,11 @@ namespace gear {
|
|||
case WORKSTOP:
|
||||
return signalStop (now, executionCtx);
|
||||
case NOTIFY:
|
||||
return dispatch (now, executionCtx); //▷ special processing for the Notification
|
||||
return postNotify (now, executionCtx);
|
||||
case POST:
|
||||
return postSelf (now, executionCtx);
|
||||
case GATE:
|
||||
return checkGate (now, executionCtx);
|
||||
case POST:
|
||||
return dispatchSelf (Time{data_.timeWindow.life},Time{data_.timeWindow.dead}, executionCtx);
|
||||
case FEED:
|
||||
return activity::PASS;
|
||||
case HOOK:
|
||||
|
|
@ -673,6 +668,11 @@ namespace gear {
|
|||
* by invoking the `post`-λ on the \a executionCtx, or by _activating_
|
||||
* a `POST`-Activity. Control flow passing here has acquired the `GroomingToken`
|
||||
* and can thus assume single threaded execution until `WORKSTART`.
|
||||
*
|
||||
* Notably this entrance is used to implement _gating_ to wait for prerequisites;
|
||||
* when a notification is passed to a `GATE`-Activity, the embedded counter is
|
||||
* decremented; after all prerequisites are „checked off“ this way, the
|
||||
* Activity-chain behind the Gate is activated.
|
||||
* @param now the scheduler-time; assuming that a call through the `post`-λ will
|
||||
* only be actually de-queued when scheduler-time equals the start time
|
||||
* defined in the POST activity and passed through the `post`-λ as parameter.
|
||||
|
|
@ -688,46 +688,18 @@ namespace gear {
|
|||
activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
|
||||
switch (verb_) {
|
||||
case NOTIFY:
|
||||
return notifyTarget (now, executionCtx);
|
||||
case POST:
|
||||
case FEED: // signal just to proceed with next...
|
||||
return activity::PASS;
|
||||
case GATE:
|
||||
return receiveGateNotification (now);
|
||||
case HOOK:
|
||||
return notifyHook (now, executionCtx);
|
||||
default:
|
||||
return activate (now, executionCtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special operation to receive a message or trigger from some other Activity.
|
||||
* Notably this is used to implement _gating_ to wait for prerequisites; when
|
||||
* a notification is passed to a `GATE`-Activity, the embedded counter is
|
||||
* decremented; after all prerequisites are „checked off“ this way, the
|
||||
* Activity-chain behind the Gate is activated.
|
||||
* @note this function is invoked from the context of the source, and
|
||||
* thus any follow-up actions beyond that scope are re-POSTed,
|
||||
* after possibly performing the GATE-check.
|
||||
*/
|
||||
template<class EXE>
|
||||
activity::Proc
|
||||
Activity::notify (Time now, EXE& executionCtx)
|
||||
{
|
||||
activity::_verify_usable_as_ExecutionContext<EXE>();
|
||||
|
||||
switch (verb_) {
|
||||
case GATE:
|
||||
return receiveGateNotification (now, executionCtx);
|
||||
case HOOK:
|
||||
return notifyHook (now, executionCtx);
|
||||
case POST:
|
||||
case FEED: // ▽▽▽▽▽ implies to use a deadline from the context
|
||||
return postChain (now,Time::NEVER, executionCtx);
|
||||
default:
|
||||
return dispatchSelfDelayed (now,Time::NEVER, executionCtx);
|
||||
} // Fallback: self-re-dispatch for async execution (-> getWaitDelay())
|
||||
}
|
||||
|
||||
|
||||
}} // namespace vault::gear
|
||||
#endif /*SRC_VAULT_GEAR_ACTIVITY_H_*/
|
||||
|
|
|
|||
|
|
@ -140,7 +140,6 @@ namespace gear {
|
|||
|
||||
const auto IDLE_WAIT = 20ms; ///< sleep-recheck cycle for workers deemed _idle_
|
||||
const size_t DISMISS_CYCLES = 100; ///< number of wait cycles before an idle worker terminates completely
|
||||
Offset POLL_WAIT_DELAY{FSecs(1,1000)}; ///< delay until re-evaluating after notification (obscure feature, retained for future use)
|
||||
Offset DUTY_CYCLE_PERIOD{FSecs(1,20)}; ///< period of the regular scheduler »tick« for state maintenance.
|
||||
Offset DUTY_CYCLE_TOLERANCE{FSecs(1,10)}; ///< maximum slip tolerated on duty-cycle start before triggering Scheduler-emergency
|
||||
}
|
||||
|
|
@ -559,12 +558,6 @@ namespace gear {
|
|||
return activity::PASS;
|
||||
}
|
||||
|
||||
Offset
|
||||
getWaitDelay()
|
||||
{
|
||||
return POLL_WAIT_DELAY;
|
||||
}
|
||||
|
||||
/** access high-resolution-clock, rounded to µ-Ticks */
|
||||
Time
|
||||
getSchedTime()
|
||||
|
|
|
|||
|
|
@ -240,8 +240,8 @@ namespace test {
|
|||
CHECK (detector.verifyInvocation(CTX_TICK).arg(t));
|
||||
|
||||
detector.incrementSeq();
|
||||
ctx.tick.returning(activity::KILL);
|
||||
CHECK (activity::KILL == ctx.tick(t));
|
||||
ctx.tick.returning(activity::KICK);
|
||||
CHECK (activity::KICK == ctx.tick(t));
|
||||
CHECK (detector.verifyInvocation(CTX_TICK).timeArg(t));
|
||||
|
||||
CHECK (detector.verifyInvocation(CTX_WORK).timeArg(t)
|
||||
|
|
@ -360,21 +360,28 @@ namespace test {
|
|||
void
|
||||
watch_notification()
|
||||
{
|
||||
Time tt{11,11}; // start time of the NOTIFY
|
||||
Time ts{22,22}; // start time of the target-chain
|
||||
Time td{33,33}; // deadline for the target-chain
|
||||
ActivityDetector detector;
|
||||
|
||||
Activity chain;
|
||||
Activity gate{1, Time{22,22}};
|
||||
Activity gate{1, td};
|
||||
gate.next = &chain;
|
||||
Activity notification{&gate};
|
||||
Activity notification{&gate, ts}; // note: follow-up start time `ts` injected here
|
||||
CHECK (gate.data_.condition.rest == 1);
|
||||
|
||||
detector.insertActivationTap (notification.data_.notification.target);
|
||||
|
||||
Time tt{11,11};
|
||||
notification.dispatch (tt, detector.executionCtx);
|
||||
notification.activate (tt, detector.executionCtx); // dispatch time `tt` (is actually irrelevant here)
|
||||
// activating the NOTIFY causes it to POST its target, thereby setting the deadline from the GATE
|
||||
CHECK (detector.verifyInvocation("CTX-post").arg("22.022","33.033", "tap-GATE", "≺test::CTX≻"));
|
||||
|
||||
CHECK (detector.verifyInvocation("tap-GATE").arg("11.011 --notify-↯> Act(GATE")
|
||||
.beforeInvocation("CTX-post").arg("11.011","22.022", "Act(TICK", "≺test::CTX≻"));
|
||||
detector.incrementSeq();
|
||||
// to see the effect of the instrumentation, we need to mimic the behaviour of λ-post,
|
||||
// which is to call Activity::dispatch() on the given target
|
||||
notification.data_.notification.target->dispatch (ts, detector.executionCtx); // note: using `ts` for the follow-up chain
|
||||
CHECK (detector.verifyInvocation("tap-GATE").seq(1).arg("22.022 --notify-↯> Act(GATE"));
|
||||
CHECK (gate.data_.condition.rest == 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ namespace test {
|
|||
using lib::time::FSecs;
|
||||
using lib::time::Offset;
|
||||
using lib::meta::RebindVariadic;
|
||||
using util::unConst;
|
||||
using util::isnil;
|
||||
using std::forward;
|
||||
using std::move;
|
||||
|
|
@ -119,7 +120,6 @@ namespace test {
|
|||
const string CTX_DONE{"CTX-done"};
|
||||
const string CTX_TICK{"CTX-tick"};
|
||||
|
||||
Offset POLL_WAIT_DELAY{FSecs(1)};
|
||||
Time SCHED_TIME_MARKER{555,5}; ///< marker value for "current scheduler time" used in tests
|
||||
}
|
||||
|
||||
|
|
@ -355,61 +355,80 @@ namespace test {
|
|||
{
|
||||
Logger log_;
|
||||
TimeVar invoked_{Time::ANYTIME};
|
||||
|
||||
|
||||
Activity*
|
||||
target()
|
||||
{
|
||||
return reinterpret_cast<Activity*> (data_.callback.arg);
|
||||
}
|
||||
|
||||
Activity const*
|
||||
target() const
|
||||
{
|
||||
return unConst(this)->target();
|
||||
}
|
||||
|
||||
activity::Proc
|
||||
activation ( Activity& thisHook
|
||||
, Time now
|
||||
, void* executionCtx) override
|
||||
{
|
||||
REQUIRE (thisHook.is (Activity::HOOK));
|
||||
invoked_ = now;
|
||||
if (data_.callback.arg == 0)
|
||||
{// no adapted target; just record this activation
|
||||
log_(util::toString(now) + " ⧐ ");
|
||||
return activity::PASS;
|
||||
}
|
||||
else
|
||||
{// forward activation to the adapted target Activity
|
||||
Activity& target = *reinterpret_cast<Activity*> (data_.callback.arg);
|
||||
auto ctx = *static_cast<FakeExecutionCtx*> (executionCtx);
|
||||
log_(util::toString(now) + " ⧐ " + util::toString (target));
|
||||
return target.activate (now, ctx);
|
||||
}
|
||||
}
|
||||
{
|
||||
REQUIRE (thisHook.is (Activity::HOOK));
|
||||
invoked_ = now;
|
||||
if (not target())
|
||||
{// no adapted target; just record this activation
|
||||
log_(util::toString(now) + " ⧐ ");
|
||||
return activity::PASS;
|
||||
}
|
||||
else
|
||||
{// forward activation to the adapted target Activity
|
||||
auto ctx = *static_cast<FakeExecutionCtx*> (executionCtx);
|
||||
log_(util::toString(now) + " ⧐ " + util::toString (*target()));
|
||||
return target()->activate (now, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
activity::Proc
|
||||
notify ( Activity& thisHook
|
||||
, Time now
|
||||
, void* executionCtx) override
|
||||
{
|
||||
REQUIRE (thisHook.is (Activity::HOOK));
|
||||
invoked_ = now;
|
||||
if (data_.callback.arg == 0)
|
||||
{// no adapted target; just record this notification
|
||||
log_(util::toString(now) + " --notify-↯• ");
|
||||
return activity::PASS;
|
||||
}
|
||||
else
|
||||
{// forward notification-dispatch to the adapted target Activity
|
||||
Activity& target = *reinterpret_cast<Activity*> (data_.callback.arg);
|
||||
auto ctx = *static_cast<FakeExecutionCtx*> (executionCtx);
|
||||
log_(util::toString(now) + " --notify-↯> " + util::toString (target));
|
||||
return target.notify (now, ctx);
|
||||
}
|
||||
}
|
||||
{
|
||||
REQUIRE (thisHook.is (Activity::HOOK));
|
||||
invoked_ = now;
|
||||
if (not target())
|
||||
{// no adapted target; just record this notification
|
||||
log_(util::toString(now) + " --notify-↯• ");
|
||||
return activity::PASS;
|
||||
}
|
||||
else
|
||||
{// forward notification-dispatch to the adapted target Activity
|
||||
auto ctx = *static_cast<FakeExecutionCtx*> (executionCtx);
|
||||
log_(util::toString(now) + " --notify-↯> " + util::toString (*target()));
|
||||
return target()->dispatch (now, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
diagnostic() const override
|
||||
{
|
||||
return "Probe("+string{log_}+")";
|
||||
}
|
||||
Time
|
||||
getDeadline() const override
|
||||
{
|
||||
if (target() and target()->is(Activity::GATE))
|
||||
return target()->data_.condition.getDeadline();
|
||||
else
|
||||
return Time::NEVER;
|
||||
}
|
||||
|
||||
std::string
|
||||
diagnostic() const override
|
||||
{
|
||||
return "Probe("+string{log_}+")";
|
||||
}
|
||||
|
||||
public:
|
||||
ActivityProbe (string id, EventLog& masterLog, uint const& invocationSeqNr)
|
||||
: Activity{*this, 0}
|
||||
, log_{id, masterLog, invocationSeqNr}
|
||||
{ }
|
||||
|
||||
|
||||
ActivityProbe (Activity const& subject, string id, EventLog& masterLog, uint const& invocationSeqNr)
|
||||
: Activity{*this, reinterpret_cast<size_t> (&subject)}
|
||||
, log_{id, masterLog, invocationSeqNr}
|
||||
|
|
@ -428,7 +447,7 @@ namespace test {
|
|||
{
|
||||
if (act and act->verb_ == HOOK)
|
||||
{
|
||||
ActivityProbe* probe = dynamic_cast<ActivityProbe*> (act->data_.callback.hook);
|
||||
ActivityProbe* probe = dynamic_cast<ActivityProbe*> (act->data_.callback.hook);
|
||||
if (probe)
|
||||
return probe->invoked_;
|
||||
}
|
||||
|
|
@ -591,7 +610,6 @@ namespace test {
|
|||
_DiagnosticFun<SIG_done>::Type done;
|
||||
_DiagnosticFun<SIG_tick>::Type tick;
|
||||
|
||||
function<Offset()> getWaitDelay = [] { return POLL_WAIT_DELAY; };
|
||||
function<Time()> getSchedTime = [this]{ return SCHED_TIME_MARKER;};
|
||||
|
||||
FakeExecutionCtx (ActivityDetector& detector)
|
||||
|
|
|
|||
|
|
@ -60,11 +60,11 @@ namespace test {
|
|||
|
||||
verifyActivity_Post();
|
||||
verifyActivity_Invoke();
|
||||
verifyActivity_Notify_activate();
|
||||
verifyActivity_Notify_dispatch();
|
||||
verifyActivity_Notify();
|
||||
verifyActivity_Gate_pass();
|
||||
verifyActivity_Gate_dead();
|
||||
verifyActivity_Gate_block();
|
||||
verifyActivity_Gate_notify();
|
||||
verifyActivity_Gate_opened();
|
||||
|
||||
termBuilder();
|
||||
|
|
@ -157,16 +157,16 @@ namespace test {
|
|||
|
||||
/** @test behaviour of Activity::NOTIFY when _activated_
|
||||
* - notification is dispatched as special message to an indicated target Activity
|
||||
* - when activated, a `NOTIFY`-Activity _dispatches_ into the Activity::notify()
|
||||
* of the target Activity
|
||||
* - what happens then depends on the target
|
||||
* - usually the target is a `GATE` (see below), but here for sake of simplicity,
|
||||
* a `TICK`-Activity is used; on notification, this will _post_ itself as new task,
|
||||
* with a delay retrieved from context (here configured to be +1sec), and without
|
||||
* specifying a deadline (thus a deadline from the context will be used).
|
||||
* - when activated, a `NOTIFY`-Activity invokes the λ-post _with its target,_
|
||||
* - in the actual setup (Scheduler) this leads to [dispatching](\ref Activity::dispatch)
|
||||
* of said target Activity
|
||||
* - what happens then depends on the target; usually the target is a `GATE`
|
||||
* - in first example here, we just use a `TICK`-Activity
|
||||
* - for a `GATE` there is special treatment to inject the _timing window of the target_
|
||||
* into the CTX-post invocation; this is essential to handle long notification-chains properly.
|
||||
*/
|
||||
void
|
||||
verifyActivity_Notify_activate()
|
||||
verifyActivity_Notify()
|
||||
{
|
||||
Activity chain;
|
||||
Activity notify{&chain};
|
||||
|
|
@ -174,27 +174,20 @@ namespace test {
|
|||
ActivityDetector detector;
|
||||
Time tt{111,11};
|
||||
notify.activate (tt, detector.executionCtx);
|
||||
CHECK (detector.verifyInvocation("CTX-post").arg("11.111", Time::NEVER, "Act(TICK", "≺test::CTX≻"));
|
||||
|
||||
CHECK (detector.verifyInvocation("CTX-post").arg("12.111", Time::NEVER, "Act(TICK", "≺test::CTX≻"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test behaviour of Activity::NOTIFY when activation leads to a _dispatch_
|
||||
* - when _posting_ a `NOTIFY`, a dedicated _notification_ function is invoked on the chain
|
||||
* - what actually happens then depends on the receiver; here we just activate a test-Tap
|
||||
*/
|
||||
void
|
||||
verifyActivity_Notify_dispatch()
|
||||
{
|
||||
ActivityDetector detector;
|
||||
// use a diagnostic Tap as chain to detect passing of notification
|
||||
Activity notify{detector.buildActivationProbe("notifyTargetActivity")};
|
||||
detector.incrementSeq();
|
||||
// now we use a `GATE` as target
|
||||
Time ts{333,33};
|
||||
Time td{555,55};
|
||||
Activity gate{1,td};
|
||||
notify.data_.notification.target = &gate;
|
||||
notify.data_.notification.timing = ts; // start time hint can be packaged into the notification
|
||||
|
||||
Time tt{111,11};
|
||||
notify.dispatch (tt, detector.executionCtx);
|
||||
|
||||
CHECK (detector.verifyInvocation("notifyTargetActivity").arg("11.111"));
|
||||
notify.activate (tt, detector.executionCtx);
|
||||
CHECK (detector.verifySeqIncrement(1)
|
||||
.beforeInvocation("CTX-post").arg("33.333", "55.555", "Act(GATE", "≺test::CTX≻"));
|
||||
// NOTE: △△△ start △△△ deadline
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -277,14 +270,39 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
/** @test behaviour of Activity::GATE:
|
||||
* - if it is _dispatched_ as new chain, instead of just _activating_
|
||||
* it of part of an ongoing chain, the Gate will receive a *notification*
|
||||
* - this results in _decrementing_ the prerequisite latch in the Gate
|
||||
* - what happens then depends on current state; in this test case
|
||||
* the Gate is decremented yet remains closed
|
||||
*/
|
||||
void
|
||||
verifyActivity_Gate_notify()
|
||||
{
|
||||
Activity chain;
|
||||
Activity gate{23};
|
||||
gate.next = &chain;
|
||||
|
||||
ActivityDetector detector;
|
||||
Activity& entrance = detector.buildGateWatcher (gate);
|
||||
|
||||
Time tt{333,33};
|
||||
CHECK (activity::SKIP == entrance.dispatch (tt, detector.executionCtx));
|
||||
CHECK (22 == gate.data_.condition.rest); // prerequisite-count decremented
|
||||
|
||||
CHECK (detector.verifyInvocation("tap-GATE").arg("33.333 --notify-↯> Act(GATE"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test behaviour of Activity::GATE on notification
|
||||
* - Gate configured initially such that it blocks
|
||||
* (without violating deadline)
|
||||
* - thus a regular activation signals to skip the chain,
|
||||
* but also re-schedules a further check into the future
|
||||
* - thus a regular activation signals to skip the chain.
|
||||
* - when receiving a notification, the latch is decremented
|
||||
* - if this causes the Gate to open, the chain is immediately
|
||||
* scheduled for activation, but the Gate also locked forever
|
||||
* - if this causes the Gate to open, the follow-up chain will
|
||||
* be activated immediately, but the Gate also locked forever
|
||||
* - neither a further activation, nor a further notification
|
||||
* has any effect after this point...
|
||||
*/
|
||||
|
|
@ -303,27 +321,26 @@ namespace test {
|
|||
CHECK (gate.data_.condition.dead == td);
|
||||
|
||||
ActivityDetector detector;
|
||||
Activity& wiring = detector.buildGateWatcher (gate);
|
||||
Activity& entrance = detector.buildGateWatcher (gate);
|
||||
|
||||
// an attempt to activate blocks (returning SKIP, nothing else happens)
|
||||
CHECK (activity::SKIP == wiring.activate (tt, detector.executionCtx));
|
||||
CHECK (1 == gate.data_.condition.rest); // unchanged (and locked)...
|
||||
CHECK (activity::SKIP == entrance.activate (tt, detector.executionCtx));
|
||||
CHECK (1 == gate.data_.condition.rest); // unchanged (and locked)...
|
||||
CHECK (detector.verifyInvocation("tap-GATE").arg("33.333 ⧐ Act(GATE"));
|
||||
|
||||
detector.incrementSeq();
|
||||
// Gate receives a notification from some prerequisite Activity
|
||||
CHECK (activity::PASS == wiring.notify(tt, detector.executionCtx));
|
||||
CHECK (activity::PASS == entrance.dispatch(tt, detector.executionCtx));
|
||||
CHECK (0 == gate.data_.condition.rest); // condition has been decremented...
|
||||
|
||||
CHECK (detector.verifyInvocation("tap-GATE").seq(0).arg("33.333 ⧐ Act(GATE")
|
||||
.beforeInvocation("tap-GATE").seq(1).arg("33.333 --notify-↯> Act(GATE")
|
||||
.beforeInvocation("CTX-post").seq(1).arg(tt,td, "after-GATE", "≺test::CTX≻"));
|
||||
.beforeInvocation("tap-GATE").seq(1).arg("33.333 --notify-↯> Act(GATE"));
|
||||
CHECK (gate.data_.condition.dead == Time::MIN);
|
||||
|
||||
detector.incrementSeq();
|
||||
Time ttt{444,44};
|
||||
// when another activation happens later, it is blocked to prevent double activation
|
||||
CHECK (activity::SKIP == wiring.activate (ttt, detector.executionCtx));
|
||||
CHECK (activity::SKIP == entrance.activate (ttt, detector.executionCtx));
|
||||
CHECK (detector.verifyInvocation("tap-GATE").seq(2).arg("44.444 ⧐ Act(GATE"));
|
||||
CHECK (detector.ensureNoInvocation("CTX-post").seq(2)
|
||||
.afterInvocation("tap-GATE").seq(2));
|
||||
|
|
@ -331,14 +348,13 @@ namespace test {
|
|||
|
||||
detector.incrementSeq();
|
||||
// even a further notification has no effect now....
|
||||
wiring.notify(ttt, detector.executionCtx);
|
||||
CHECK (activity::SKIP == entrance.dispatch (ttt, detector.executionCtx));
|
||||
// conditionals were not touched:
|
||||
CHECK (gate.data_.condition.dead == Time::MIN);
|
||||
CHECK (gate.data_.condition.rest == 0);
|
||||
// the log shows the further notification (at Seq=3) but no dispatch happens anymore
|
||||
CHECK (detector.verifySeqIncrement(3)
|
||||
.beforeInvocation("tap-GATE").seq(3).arg("44.444 --notify-↯> Act(GATE"));
|
||||
CHECK (detector.ensureNoInvocation("CTX-post").seq(3).arg(tt, "after-GATE", "≺test::CTX≻"));
|
||||
|
||||
// cout << detector.showLog()<<endl; // HINT: use this for investigation...
|
||||
}
|
||||
|
|
@ -435,15 +451,12 @@ namespace test {
|
|||
.afterInvocation("Gate").seq(1));
|
||||
|
||||
detector.incrementSeq();
|
||||
Activity notify{post.next}; // Notification via instrumented connection to the Gate
|
||||
|
||||
CHECK (activity::PASS == ActivityLang::dispatchChain (¬ify, detector.executionCtx)); // dispatch a notification (case/seq == 2)
|
||||
CHECK (detector.verifyInvocation("Gate") .seq(2).arg("1.011 --notify-↯> Act(GATE") // ...notification dispatched towards the Gate
|
||||
.beforeInvocation("CTX-post").seq(2).arg("1.011","2.022","after-Gate","≺test::CTX≻")); // ...this opened the Gate and posted follow-up chain
|
||||
CHECK (detector.ensureNoInvocation("after-Gate").seq(2) // verify that activation was not passed out directly
|
||||
.afterInvocation("CTX-post").seq(2));
|
||||
CHECK (detector.ensureNoInvocation("CTX-tick").seq(2) // verify also the λ-tick was not invoked directly
|
||||
.afterInvocation("CTX-post").seq(2));
|
||||
// Notification via instrumented connection to the Gate (activate(NOTIFY) -> λ-post(target) -> notify GATE
|
||||
CHECK (activity::PASS == ActivityLang::dispatchChain (post.next, detector.executionCtx)); // dispatch a notification (case/seq == 2)
|
||||
CHECK (0 == gate.data_.condition.rest); // Effect of the notification is to decrement the latch
|
||||
CHECK (detector.verifyInvocation("Gate") .seq(2).arg("1.011 --notify-↯> Act(GATE") // ...notification dispatched towards the Gate
|
||||
.beforeInvocation("after-Gate").seq(2).arg("1.011 ⧐ Act(TICK") // ...this opened the Gate, passing activation...
|
||||
.beforeInvocation("CTX-tick") .seq(2).arg("1.011")); // ...to the chain, finally invoking λ-tick
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -536,17 +549,15 @@ namespace test {
|
|||
|
||||
// rig the λ-post to forward dispatch as expected in real usage
|
||||
detector.executionCtx.post.implementedAs(
|
||||
[&](Time when, Time, Activity* postedAct, auto& ctx)
|
||||
[&](Time, Time, Activity* postedAct, auto& ctx)
|
||||
{
|
||||
if (when == ctx.getSchedTime()) // only for POST to run „right now“
|
||||
return ActivityLang::dispatchChain (postedAct, ctx);
|
||||
else
|
||||
return activity::PASS;
|
||||
return ActivityLang::dispatchChain (postedAct, ctx);
|
||||
});
|
||||
|
||||
///// Case-1 : send a notification from prerequisite, but prior to activating primary-chain
|
||||
CHECK (activity::PASS == ActivityLang::dispatchChain (&trigger, detector.executionCtx));
|
||||
CHECK (detector.verifyInvocation("trigger") .seq(0).arg("5.555 --notify-↯> Act(GATE") // notification dispatched to the Gate
|
||||
CHECK (detector.verifyInvocation("CTX-post").seq(0).arg("01.000","10.000","trigger","≺test::CTX≻") // notification is POSTed (with time and deadline from target)
|
||||
.beforeInvocation("trigger") .seq(0).arg("5.555 --notify-↯> Act(GATE") // notification dispatched to the Gate (note: now using curr-sched-time 5.555)
|
||||
.arg("<2, until 0:00:10.000")); // Note: the Gate-latch expects 2 notifications
|
||||
CHECK (detector.ensureNoInvocation("testJob") // ==> the latch was decremented but no invocation yet
|
||||
.afterInvocation("trigger"));
|
||||
|
|
@ -554,9 +565,9 @@ namespace test {
|
|||
///// Case-2 : now activate the primary-chain
|
||||
detector.incrementSeq();
|
||||
CHECK (activity::PASS == ActivityLang::dispatchChain (&anchor, detector.executionCtx));
|
||||
CHECK (detector.verifyInvocation("deBlock") .seq(1).arg("5.555 --notify-↯> Act(GATE") // immediately at begin, the internal self-notification is dispatched towards the Gate
|
||||
.arg("<1, until 0:00:10.000") // Note: at this point, the Gate-latch expects 1 notifications
|
||||
.beforeInvocation("CTX-post").seq(1).arg("5.555","10.0","after-theGate","≺test::CTX≻") //==> latch was decremented, Gate OPENS, posting the tail-chain with Deadline from Gate
|
||||
CHECK (detector.verifyInvocation("CTX-post").seq(1).arg("01.000","10.000","deBlock","≺test::CTX≻") // at begin, the internal self-notification is POSTed (with time and deadline this chain)
|
||||
.beforeInvocation("deBlock") .seq(1).arg("5.555 --notify-↯> Act(GATE") // and this call is immediately dispatched towards the Gate (using curr-sched-time 5.555)
|
||||
.arg("<1, until 0:00:10.000") // Note: at this point, the Gate-latch expects 1 notifications ==> latch decremented, Gate OPENS
|
||||
.beforeInvocation("after-theGate") .arg("5.555 ⧐ Act(WORKSTART") // ...causing the activation to pass behind the Gate
|
||||
.beforeInvocation("CTX-work").seq(1).arg("5.555","") // ...through WORKSTART
|
||||
.beforeInvocation("testJob") .seq(1).arg("7.007",12345) // ...then invoke the JobFunctor itself (with the nominal Time{7,7})
|
||||
|
|
@ -568,8 +579,9 @@ namespace test {
|
|||
|
||||
detector.incrementSeq();
|
||||
CHECK (activity::PASS == ActivityLang::dispatchChain (&trigger, detector.executionCtx)); // and any further external trigger is likewise blocked:
|
||||
CHECK (detector.verifyInvocation("trigger") .seq(2).arg("5.555 --notify-↯> Act(GATE") // ... it reaches the Gate
|
||||
.arg("<0, until -85401592:56:01.825")); // ... but the Gate has been closed permanently (by setting the deadline to Time::MIN)
|
||||
CHECK (detector.verifyInvocation("CTX-post").seq(2).arg("01.000",Time::NEVER,"trigger","≺test::CTX≻") // notification is POSTed (in the real Scheduler the deadline will block already here)
|
||||
.beforeInvocation("trigger") .seq(2).arg("5.555 --notify-↯> Act(GATE") // ... but even if it would reach the Gate...
|
||||
.arg("<0, until -85401592:56:01.825")); // ... the Gate has been closed permanently (by setting the deadline to Time::MIN)
|
||||
CHECK (detector.ensureNoInvocation("testJob") // ==> no further invocation
|
||||
.afterInvocation("trigger").seq(2));
|
||||
|
||||
|
|
@ -618,6 +630,13 @@ namespace test {
|
|||
CHECK (notify.next->data_.notification.target == followup.post().next); // was wired to the GATE of the follow-up activity Term
|
||||
CHECK (followup.post().next->is (Activity::GATE));
|
||||
|
||||
// rig the λ-post to forward dispatch as expected in real usage
|
||||
detector.executionCtx.post.implementedAs(
|
||||
[&](Time, Time, Activity* postedAct, auto& ctx)
|
||||
{
|
||||
return ActivityLang::dispatchChain (postedAct, ctx);
|
||||
});
|
||||
|
||||
|
||||
///// Case-1 : trigger off the async IO job
|
||||
CHECK (activity::PASS == ActivityLang::dispatchChain (&anchor, detector.executionCtx));
|
||||
|
|
@ -631,7 +650,10 @@ namespace test {
|
|||
detector.incrementSeq();
|
||||
CHECK (activity::PASS == ActivityLang::dispatchChain (¬ify, detector.executionCtx));
|
||||
CHECK (detector.verifyInvocation("CTX-done").seq(1).arg("5.555", "") // activation of WORKSTOP via callback
|
||||
.beforeInvocation("CTX-post").seq(1).arg("5.555","10.0","WORKSTART","≺test::CTX≻"));// the attached chain is activated, POSTing the second Activity
|
||||
.beforeInvocation("CTX-post").seq(1).arg("01.00","10.00","GATE","≺test::CTX≻") // the notification posts the GATE of the follow-up chain
|
||||
.beforeInvocation("CTX-work").seq(1).arg("5.555", "") // GATE passes -> activation of the follow-up work commences
|
||||
.beforeInvocation("calcJob") .seq(1)
|
||||
.beforeInvocation("CTX-done").seq(1).arg("5.555", ""));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -80833,7 +80833,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<arrowlink COLOR="#e3fddf" DESTINATION="ID_229335349" ENDARROW="Default" ENDINCLINATION="46;-190;" ID="Arrow_ID_382638651" STARTARROW="None" STARTINCLINATION="-301;39;"/>
|
||||
<linktarget COLOR="#dae9fa" DESTINATION="ID_1532008023" ENDARROW="Default" ENDINCLINATION="-184;505;" ID="Arrow_ID_61418953" SOURCE="ID_1073489318" STARTARROW="None" STARTINCLINATION="630;34;"/>
|
||||
<node CREATED="1690069222750" ID="ID_276634248" MODIFIED="1690494867733" TEXT="λ-post">
|
||||
<node CREATED="1690736737684" FOLDED="true" ID="ID_1359419273" MODIFIED="1697930193115" TEXT="(Time, Activity, ExecutionCtx) ⟼ activity::Proc">
|
||||
<node CREATED="1690736737684" FOLDED="true" ID="ID_1359419273" MODIFIED="1702599896296" TEXT="(Time,Time, Activity, ExecutionCtx) ⟼ activity::Proc">
|
||||
<node COLOR="#435e98" CREATED="1697929874025" ID="ID_1875907326" MODIFIED="1697930180261" TEXT="warum hier der ExecutionCtx (nochmal) als Argument?">
|
||||
<linktarget COLOR="#87a6b3" DESTINATION="ID_1875907326" ENDARROW="Default" ENDINCLINATION="543;939;" ID="Arrow_ID_1742040512" SOURCE="ID_1585090015" STARTARROW="None" STARTINCLINATION="271;21;"/>
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
|
|
@ -80982,7 +80982,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1693316943383" FOLDED="true" ID="ID_816321833" MODIFIED="1702432330779" TEXT="Redundanz in den Deadline-Angaben">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1693316943383" FOLDED="true" ID="ID_816321833" MODIFIED="1702599768360" TEXT="Redundanz in den Deadline-Angaben">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -81267,9 +81267,138 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node COLOR="#338800" CREATED="1702440166840" ID="ID_880220704" MODIFIED="1702441899698" TEXT="stattdessen direkt NOTIFY.activate() ⟶ dispatch gehen">
|
||||
<arrowlink COLOR="#72949f" DESTINATION="ID_1566309423" ENDARROW="Default" ENDINCLINATION="169;0;" ID="Arrow_ID_942543086" STARTARROW="None" STARTINCLINATION="184;9;"/>
|
||||
<arrowlink COLOR="#85c5af" DESTINATION="ID_1861186167" ENDARROW="Default" ENDINCLINATION="683;22;" ID="Arrow_ID_1560412883" STARTARROW="None" STARTINCLINATION="275;13;"/>
|
||||
<arrowlink COLOR="#85c5af" DESTINATION="ID_1861186167" ENDARROW="Default" ENDINCLINATION="683;22;" ID="Arrow_ID_1560412883" STARTARROW="None" STARTINCLINATION="539;27;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1702577370950" ID="ID_650472693" MODIFIED="1702600287956" TEXT="Fehler in der Vereinfachung: Concurrency übersehen">
|
||||
<arrowlink COLOR="#5b2e58" DESTINATION="ID_1696260440" ENDARROW="Default" ENDINCLINATION="664;-27;" ID="Arrow_ID_1904329782" STARTARROW="None" STARTINCLINATION="420;245;"/>
|
||||
<linktarget COLOR="#ad0013" DESTINATION="ID_650472693" ENDARROW="Default" ENDINCLINATION="-796;37;" ID="Arrow_ID_1470263046" SOURCE="ID_599055156" STARTARROW="None" STARTINCLINATION="193;-386;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1702577545878" ID="ID_1574266507" MODIFIED="1702577600295">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<i>vor </i>dem Zugang zum <font face="Monospaced" color="#542418">GATE</font> muß das <b>Grooming-Token</b>  erlangt werden
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1702577675716" ID="ID_427980935" MODIFIED="1702577682880" TEXT="Datenänderung: count-down-Latch"/>
|
||||
<node CREATED="1702577684769" ID="ID_1888418957" MODIFIED="1702577707778" TEXT="könnte theoretisch zu Fehlentscheidungen wegen (un)Sichtbarkeit führen">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1702577718673" ID="ID_401029061" MODIFIED="1702577764896" TEXT="↯ widerspricht dem Prinzip: Ablaufsteuerung nur im »management-Modus«"/>
|
||||
</node>
|
||||
<node CREATED="1702577613141" ID="ID_1657872854" MODIFIED="1702577648692" TEXT="(im Rückblick könnte das der Grund für die doppelte Indirektion durch λ-post gewesen sein)">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1702602291539" ID="ID_1914905944" MODIFIED="1702602435718">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
zweimaliger λ-post wäre die <b>sauberste Lösung</b> — bedingt aber inakzeptablen <b>Overhead</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="closed"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702602438725" ID="ID_1887124069" MODIFIED="1702602464551" TEXT="in einen λ-post kombinieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1702602467423" ID="ID_975246504" MODIFIED="1702602501393" TEXT="die Platzierung dieses Aufrufs ist limitiert">
|
||||
<node CREATED="1702602502495" ID="ID_1400223035" MODIFIED="1702602543154" TEXT="es muß die »Markierung« als NOTIFY mitgegeben werden"/>
|
||||
<node CREATED="1702602544283" ID="ID_1348984098" MODIFIED="1702602559537" TEXT="im Grunde würden wir zwei verschiedene λ-Eingänge brauchen"/>
|
||||
<node CREATED="1702603270638" ID="ID_1296023821" MODIFIED="1702603278030" TEXT="allerdings nur für GATE und HOOK">
|
||||
<node CREATED="1702604288353" ID="ID_683517628" MODIFIED="1702604315094" TEXT="formal ist es ein double-dispatch — der aber nur in wenigen Fällen auftritt"/>
|
||||
<node CREATED="1702604317714" ID="ID_1505479076" MODIFIED="1702604338195" TEXT="man könnte diese Fälle in die Bedeutung von »POST« einfalten">
|
||||
<node CREATED="1702604346422" ID="ID_612274060" MODIFIED="1702604353025" TEXT="weil es zu keiner Kollision kommt"/>
|
||||
<node CREATED="1702604353791" ID="ID_245763948" MODIFIED="1702604365437" TEXT="weil die meisten Activities gar nicht gePOSTet werden"/>
|
||||
<node CREATED="1702604396352" ID="ID_1049603188" MODIFIED="1702604429647" TEXT="weil λ-post selber den Charakter des »Signalisierens« hat"/>
|
||||
</node>
|
||||
<node CREATED="1702605173602" ID="ID_1094490055" MODIFIED="1702605309570" TEXT="hab dabei aber ein schlechtes Gefühl">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1702604567601" ID="ID_1021845654" MODIFIED="1702604585404" TEXT="Zugang zum Timing-Window ist ebenfalls problematisch">
|
||||
<node CREATED="1702604659955" ID="ID_1418126303" MODIFIED="1702604683978" TEXT="weil diese Info auf Activity-Ebene meist nicht vorliegt"/>
|
||||
<node CREATED="1702604989888" ID="ID_147783305" MODIFIED="1702605023744" TEXT="auch aus Platzgründen">
|
||||
<node CREATED="1702605024836" ID="ID_1727350374" MODIFIED="1702605026331" TEXT="sie wird nur zum Scheduling gebraucht"/>
|
||||
<node CREATED="1702605027180" ID="ID_891601423" MODIFIED="1702605038563" TEXT="Scheduling hat inzwischen seine eigene Datenstruktur"/>
|
||||
<node CREATED="1702605039282" ID="ID_892450996" MODIFIED="1702605051735" TEXT="Activity beschreibt Ausführungs-Logik"/>
|
||||
</node>
|
||||
<node CREATED="1702605512819" ID="ID_1007164080" MODIFIED="1702605584773" TEXT="im NOTIFY-Fall muß man einen Kniff anwenden">
|
||||
<node CREATED="1702605614645" ID="ID_404496788" MODIFIED="1702605631111" TEXT="ein Hint auf den Zeitpunkt könnte im NOTIFY untergebracht werden"/>
|
||||
<node CREATED="1702605632651" ID="ID_559967093" MODIFIED="1702605644853" TEXT="eine spezielle Deadline kann man dem GATE entnehmen"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1702605660894" ID="ID_1205243179" MODIFIED="1702605670658" TEXT="damit zeichnet sich folgende Lösung ab....">
|
||||
<node CREATED="1702605687260" ID="ID_1998074267" MODIFIED="1702605713588" TEXT="ein »POST-from-Activity« muß stets eigens vorbereitet werden"/>
|
||||
<node CREATED="1702605748956" ID="ID_812540974" MODIFIED="1702605764921" TEXT="die angezeigte Traget-Activity bestimmt was geschieht">
|
||||
<node CREATED="1702605766273" ID="ID_1665629824" MODIFIED="1702605779451" TEXT="POST ⟶ activate chain"/>
|
||||
<node CREATED="1702605840622" ID="ID_1623162924" MODIFIED="1702605857560" TEXT="GATE ⟶ notifyGate"/>
|
||||
<node CREATED="1702605863196" ID="ID_1280842359" MODIFIED="1702605869407" TEXT="HOOK ⟶ notifyHook"/>
|
||||
<node CREATED="1702605875634" ID="ID_1029394228" MODIFIED="1702605925638" TEXT="else ⟶ activate"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1702610771036" ID="ID_785523016" MODIFIED="1702610777206" TEXT="TODO: offen">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node CREATED="1702610778957" ID="ID_1196414966" MODIFIED="1702610785877" TEXT="der Umgang mit dem Hook">
|
||||
<node CREATED="1702767308131" ID="ID_931273066" MODIFIED="1702767330240" TEXT="das ist ein »Lackmus-Test« für das Design..."/>
|
||||
<node CREATED="1702767352010" ID="ID_1029846387" MODIFIED="1702767369837">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
wie gut ist es <i>self-composable?</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1702767461236" ID="ID_1489450472" MODIFIED="1702767480525" TEXT="der Hook soll offen bleiben und verschiedenenen Zwecken dienen können">
|
||||
<node CREATED="1702767481917" ID="ID_1061078866" MODIFIED="1702767495875" TEXT="ein konkret bekannter Zweck: Instrumentierung"/>
|
||||
<node CREATED="1702767496655" ID="ID_229116438" MODIFIED="1702767548514">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
aber der Hook kann auch die Rolle jedes<i> activate/notify </i>übernehmen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1702767586803" ID="ID_737616449" MODIFIED="1702767614579" TEXT="⟹ Schlußfolgerung: für »notify« braucht es eine Vorab-Kanal: getDeadline()"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1702610797904" ID="ID_1129530768" MODIFIED="1702767389086" TEXT="kann in dem Fall nicht die Startzeit durchreichen">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1702767404708" ID="ID_1124188477" MODIFIED="1702767409584" TEXT="warum nicht?"/>
|
||||
<node CREATED="1702767411220" ID="ID_1325784626" MODIFIED="1702767417625" TEXT="springt nichts dagegen"/>
|
||||
<node CREATED="1702767433823" ID="ID_805853765" MODIFIED="1702767454074" TEXT="Hook bekommt ja die gewählte Zeit „in die Hand“"/>
|
||||
</node>
|
||||
<node CREATED="1702610969672" ID="ID_1632101586" MODIFIED="1702610978779" TEXT="ansonsten "sollte" es schon fertig sein...">
|
||||
<node CREATED="1702610981163" ID="ID_1295589775" MODIFIED="1702610990648" TEXT="is eigentlich einfacher geworden"/>
|
||||
<node CREATED="1702610991285" ID="ID_967899840" MODIFIED="1702611000392" TEXT="bis auf die Asymertrien">
|
||||
<node CREATED="1702611001140" ID="ID_1030909980" MODIFIED="1702611004224" TEXT="mit dem TimeWindow"/>
|
||||
<node CREATED="1702611004693" ID="ID_648606411" MODIFIED="1702611007201" TEXT="mit dem Hook"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1702438679407" ID="ID_1796428489" MODIFIED="1702440355290" TEXT="semantisch">
|
||||
|
|
@ -81499,6 +81628,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1690495433254" ID="ID_1805822057" MODIFIED="1692569069328" TEXT="aus Konsistenz-Gründen indirekter Dispatch (u.U asynchron)">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702599990156" ID="ID_1696260440" MODIFIED="1702600277173" TEXT="re-scheduling: Zeitpunkt und Deadline gemäß NOTIFY-target setzen">
|
||||
<linktarget COLOR="#a3385d" DESTINATION="ID_1696260440" ENDARROW="Default" ENDINCLINATION="-1273;54;" ID="Arrow_ID_458002858" SOURCE="ID_226925697" STARTARROW="None" STARTINCLINATION="-900;-46;"/>
|
||||
<linktarget COLOR="#5b2e58" DESTINATION="ID_1696260440" ENDARROW="Default" ENDINCLINATION="664;-27;" ID="Arrow_ID_1904329782" SOURCE="ID_650472693" STARTARROW="None" STARTINCLINATION="420;245;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node CREATED="1690069846556" ID="ID_681493814" MODIFIED="1690495242907" TEXT="λ-post">
|
||||
<arrowlink COLOR="#8897a9" DESTINATION="ID_817512371" ENDARROW="Default" ENDINCLINATION="-175;61;" ID="Arrow_ID_847368059" STARTARROW="None" STARTINCLINATION="-262;0;"/>
|
||||
</node>
|
||||
|
|
@ -85461,7 +85595,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1697982818498" FOLDED="true" ID="ID_136482882" MODIFIED="1702431643920" TEXT="Deadline berücksichtigen ">
|
||||
<node COLOR="#338800" CREATED="1697982818498" FOLDED="true" ID="ID_136482882" MODIFIED="1702599821631" TEXT="Deadline berücksichtigen ">
|
||||
<linktarget COLOR="#47a6ef" DESTINATION="ID_136482882" ENDARROW="Default" ENDINCLINATION="69;-169;" ID="Arrow_ID_63115321" SOURCE="ID_337384722" STARTARROW="None" STARTINCLINATION="-285;-30;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1697982844409" ID="ID_1374530988" MODIFIED="1697982854041" TEXT="im Datenrecord mitführen"/>
|
||||
|
|
@ -103270,8 +103404,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#435e98" CREATED="1702441785767" ID="ID_720337177" MODIFIED="1702495206270" TEXT="Maßnahmen">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node COLOR="#338800" CREATED="1702441683718" ID="ID_1861186167" MODIFIED="1702443370493" TEXT="Vereinfachung in der Sprachauswertung beseitigt viele redundante λ-post">
|
||||
<linktarget COLOR="#85c5af" DESTINATION="ID_1861186167" ENDARROW="Default" ENDINCLINATION="683;22;" ID="Arrow_ID_1560412883" SOURCE="ID_880220704" STARTARROW="None" STARTINCLINATION="275;13;"/>
|
||||
<node COLOR="#338800" CREATED="1702441683718" ID="ID_1861186167" MODIFIED="1702577486299" TEXT="Vereinfachung in der Sprachauswertung beseitigt viele redundante λ-post">
|
||||
<arrowlink COLOR="#ac316f" DESTINATION="ID_1174594521" ENDARROW="Default" ENDINCLINATION="-475;-22;" ID="Arrow_ID_358088244" STARTARROW="None" STARTINCLINATION="-246;9;"/>
|
||||
<linktarget COLOR="#85c5af" DESTINATION="ID_1861186167" ENDARROW="Default" ENDINCLINATION="683;22;" ID="Arrow_ID_1560412883" SOURCE="ID_880220704" STARTARROW="None" STARTINCLINATION="539;27;"/>
|
||||
<linktarget COLOR="#51a8aa" DESTINATION="ID_1861186167" ENDARROW="Default" ENDINCLINATION="358;14;" ID="Arrow_ID_926842783" SOURCE="ID_1209140162" STARTARROW="None" STARTINCLINATION="-197;8;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -103423,7 +103558,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#338800" CREATED="1702524831355" ID="ID_369134711" MODIFIED="1702524854572" TEXT="bestehende Funktionalität vom Activity-Term herausgeführt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1702524859081" ID="ID_203571442" MODIFIED="1702524877503" TEXT="Test — wirksam?">
|
||||
<node COLOR="#435e98" CREATED="1702524859081" ID="ID_203571442" MODIFIED="1702589541901" TEXT="Test — wirksam?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1702525345416" ID="ID_392109929" MODIFIED="1702525366979" TEXT="ja .... denke schon">
|
||||
<icon BUILTIN="smiley-oh"/>
|
||||
|
|
@ -103440,8 +103575,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
die von einem einzigen Worker durchgearbeietet werden
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1702525401353" ID="ID_1274653458" MODIFIED="1702525416941" TEXT="die meisten Invocations passieren jetzt nahe / kurz nach der nominellen Zeit"/>
|
||||
<node CREATED="1702525417791" ID="ID_917292675" MODIFIED="1702525427159" TEXT="viel mehr Wechsel zwischen den Workern"/>
|
||||
|
|
@ -103455,10 +103589,193 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
wäre ja so zu erwarten gemäß Topologie...
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1702574866457" ID="ID_124353574" MODIFIED="1702574886053" TEXT="dieser Graph ist kein gutes Beispiel">
|
||||
<node CREATED="1702574888411" ID="ID_197928028" MODIFIED="1702574896469" TEXT="er hat »Knoten« am Ende"/>
|
||||
<node CREATED="1702574904784" ID="ID_1387954804" MODIFIED="1702576637786" TEXT="eine Ketten-Berechnung ganz am Ende ist unvermeidbar">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
weil es stets ein <i>letztes Prerequisite </i>gibt, das dann die ganze Lawine an Berechnungen lostritt; der relevante Knoten ist Node-Nr.34(L20) — und die wiederum hat drei Vorläufer-Ketten der Länge 2, d.h. der <i>finale Trigger liegt auf Level 18 oder gar 17.</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1702576639336" ID="ID_1556246282" MODIFIED="1702578705819" TEXT="auffällig: »schwere« Knoten laufen excessiv lang">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1702576685969" ID="ID_1582564429" MODIFIED="1702576695636" TEXT="habe jetzt vier Beispiele gesehen"/>
|
||||
<node CREATED="1702576696354" ID="ID_1866923525" MODIFIED="1702576718501" TEXT="Node hatte jeweils weight=3 und war ein »Knoten«"/>
|
||||
<node CREATED="1702576720420" ID="ID_426903156" MODIFIED="1702576797497" TEXT="Laufzeit war etwa doppelt so lang wie erwartet">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
~3ms — aber 3·400µs ≈ 1.5ms + 100µs hätte ich erwartet
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1702577920263" ID="ID_360094217" MODIFIED="1702577924991" TEXT="weitere Beobachtungen">
|
||||
<node CREATED="1702577926003" ID="ID_1121143187" MODIFIED="1702578005428" TEXT="Node-62: Gewicht≡0 aber starker Fan-In ⟶ unauffällig (100µs)"/>
|
||||
<node CREATED="1702578258486" ID="ID_1691270037" MODIFIED="1702578648844" TEXT="Node-38: Gewicht≡3 aber starker Fan-Out≡4 ⟶ unauffällig  (1.5ms)"/>
|
||||
<node CREATED="1702578652335" ID="ID_980355200" MODIFIED="1702578670131" TEXT="Node-40: analog und  ⟶ unauffällig  (1.5ms)"/>
|
||||
<node CREATED="1702579171582" ID="ID_830629839" MODIFIED="1702579251909" TEXT="Kette 23⟶24⟶29: Gewicht≡5 �� auffällig (4ms statt 2.5)"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1702578681160" ID="ID_969532050" MODIFIED="1702578700935" TEXT="inkonclusiv">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1702579291988" ID="ID_1769177398" MODIFIED="1702589548348" TEXT="unklar: wo steckt da die Zeit?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1702579936527" ID="ID_936172430" MODIFIED="1702579954285" TEXT="weiterer Lauf mit Zeit-Log im invoke..."/>
|
||||
<node CREATED="1702579958724" ID="ID_201523785" MODIFIED="1702580074488" TEXT="Node-62: 25µs in Node + 25µs bis POST"/>
|
||||
<node CREATED="1702580218401" ID="ID_375694770" MODIFIED="1702580241884" TEXT="Node-38: 1.5ms iN + 35 bis POST"/>
|
||||
<node CREATED="1702580277764" ID="ID_1085217550" MODIFIED="1702580403446" TEXT="Node-40: 1.4ms +38µs"/>
|
||||
<node CREATED="1702580405587" ID="ID_1590478428" MODIFIED="1702581627794" TEXT="Node-23: 1.8ms + 31µs �� leicht auffällig"/>
|
||||
<node CREATED="1702580751786" ID="ID_1360589841" MODIFIED="1702580766927" TEXT="Node-24: 27µs + 27µs"/>
|
||||
<node CREATED="1702580859812" ID="ID_1310894097" MODIFIED="1702581638456" TEXT="Node-29: 1.26ms +33µs (weight≡2) �� leicht auffällig"/>
|
||||
<node CREATED="1702581052260" ID="ID_1861306020" MODIFIED="1702581098265" TEXT="Kette zusammen 3.2ms"/>
|
||||
<node CREATED="1702581424784" ID="ID_429500585" MODIFIED="1702581651798" TEXT="Node-34: 2ms +10µs in + 10µs out �� auffällig"/>
|
||||
<node CREATED="1702582029351" ID="ID_306805740" MODIFIED="1702582106370" TEXT="Node-19: 3ms +30µs in + 29µs out �� stark auffällig (weight≡2)"/>
|
||||
<node CREATED="1702582314449" ID="ID_1060550440" MODIFIED="1702582349376" TEXT="Node-20: 2ms +26µs in + 120µs out �� interessant auffällig"/>
|
||||
<node CREATED="1702582817918" ID="ID_208903662" MODIFIED="1702582844319" TEXT="Node-15: 1.5ms aber (weight≡1) �� stark auffällig"/>
|
||||
<node CREATED="1702581133914" HGAP="-6" ID="ID_26188132" MODIFIED="1702581161202" TEXT="Fazit" VSHIFT="8">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1702581142071" ID="ID_1009579756" MODIFIED="1702581528026" TEXT="unklar">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
bei genauerer Betrachtung löst sich die Feststellung auf....
|
||||
</p>
|
||||
<p>
|
||||
ja, irgendwo geht hier Zeit verloren, aber im 2.Lauf ist alles nicht so stark ausgeprägt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
</node>
|
||||
<node CREATED="1702581144757" ID="ID_481007131" MODIFIED="1702581589603" TEXT="vermutlich im CPU-Load">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
im 2.Lauf mit genauerer Instrumentierung sind die auffälligen Abweichungen <i>innerhalb</i> der Node-Invocation, nicht im administrativen Teil
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1702576822348" ID="ID_403805566" MODIFIED="1702577266690">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
beim Durchdenken nebenbei aufgefallen:<i> unprotected concurrenct acccess</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#fd3f95" DESTINATION="ID_8315180" ENDARROW="Default" ENDINCLINATION="28;-93;" ID="Arrow_ID_229684447" STARTARROW="None" STARTINCLINATION="-396;15;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1702589592702" ID="ID_1170956866" MODIFIED="1702589611834" TEXT="bestätigt: im entscheidenden Abschnitt wird parallelisiert">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1702589617758" ID="ID_1138924507" MODIFIED="1702589627221" TEXT="damit ist das wichtigste Ziel erreicht"/>
|
||||
<node CREATED="1702589628097" ID="ID_1191934434" MODIFIED="1702589750209" TEXT="das Durchmarschieren nutzt nämlich die Ressourcen nicht effizient">
|
||||
<arrowlink DESTINATION="ID_1865116529" ENDARROW="Default" ENDINCLINATION="120;0;" ID="Arrow_ID_1653871320" STARTARROW="None" STARTINCLINATION="120;0;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1702589556547" ID="ID_1028242300" MODIFIED="1702589671064" TEXT="Beobachtung: Prioritäten werden effektiv falsch gesetzt">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1702589690943" ID="ID_21620276" MODIFIED="1702589708900" TEXT="Falls eine Continuation re-scheduled wird">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1702589717677" ID="ID_1865116529" MODIFIED="1702589750209" TEXT="sofern eine Kette durchläuft, ist sie (nun garantiert) im Verzug">
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1865116529" ENDARROW="Default" ENDINCLINATION="120;0;" ID="Arrow_ID_1653871320" SOURCE="ID_1191934434" STARTARROW="None" STARTINCLINATION="120;0;"/>
|
||||
</node>
|
||||
<node CREATED="1702589757128" ID="ID_1991098320" MODIFIED="1702589773548" TEXT="wenn sie dabei aber wegen Contention unterbrochen wird...."/>
|
||||
<node CREATED="1702589774357" ID="ID_450376387" MODIFIED="1702589788431" TEXT="dann reiht sie sich in die aktuelle (verspätete) Zeit ein"/>
|
||||
<node CREATED="1702589808425" ID="ID_1970025813" MODIFIED="1702589824394" TEXT="und wartet erst mal die Folgen des aktuellen Levels ab"/>
|
||||
<node CREATED="1702589825360" ID="ID_1200779225" MODIFIED="1702589854771" TEXT="...welche aber schlimmstenfalls indirekt auf die verspätete Kette angewiesen wären"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1702589992304" ID="ID_463167560" MODIFIED="1702590019098" TEXT="das hat strukturelle Ähnlichkeit mit einer Priority-Inversion">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1702590023012" ID="ID_1246665906" MODIFIED="1702590120782" TEXT="...diese kann bei unserem Ansatz direkt nicht auftreten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...weil wir Prioritäten gar nicht auf der Ebene des Schedulers repräsentieren, sondern in den übergreifenden Plan einarbeiten können; der Scheduler muß also nur im Bezug auf diesen Plan priorisieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1702590037058" ID="ID_1545617475" MODIFIED="1702590283499" TEXT="...aber aus logischen Gründen sollte die zugrundeliegende Struktur sich irgendwo zeigen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn diese zugrundeliegende Struktur ist durch einen vorgelagerten Plan grundsätzlich nicht aus der Welt zu schaffen, denn es geht dabei um eine Diskrepanz zwischen einer planäßigen Codifizierung der Priorität und einer <i>real (sachbezogen) gegebenen </i>Priorität
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1702589858274" ID="ID_226925697" MODIFIED="1702600233715" TEXT="Korrekt wäre: Scheduing mit der Zeit des Notification-Empfängers">
|
||||
<arrowlink COLOR="#a3385d" DESTINATION="ID_1696260440" ENDARROW="Default" ENDINCLINATION="-1273;54;" ID="Arrow_ID_458002858" STARTARROW="None" STARTINCLINATION="-900;-46;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1702589914451" ID="ID_765655284" MODIFIED="1702589946767" TEXT="denn nur dadurch würde der Sinn des λ-post realisiert"/>
|
||||
<node CREATED="1702589956149" ID="ID_181976158" MODIFIED="1702589979157" TEXT="wenn der Empfänger bereits fällig wäre, dann sollte die Notification Vorrang bekommen"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1702576882672" ID="ID_8315180" MODIFIED="1702577283363" TEXT="Bugfix: concurrency für vereinfachtes NOTIFY">
|
||||
<linktarget COLOR="#fd3f95" DESTINATION="ID_8315180" ENDARROW="Default" ENDINCLINATION="28;-93;" ID="Arrow_ID_229684447" SOURCE="ID_403805566" STARTARROW="None" STARTINCLINATION="-396;15;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1702576947842" ID="ID_1174594521" LINK="#ID_1805822057" MODIFIED="1702600107582" TEXT="hab bei meinen Vereinfachungen vorgestern die Concurrency übersehen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...ich hatte dabei ein ungutes Gefühl, weil ich mir nicht erklären konnte, warum um ursprünglichen Code diese doppelte Indirektion drinnen war; hab das dann vom Tisch gewischt mit der Vermutung, es sei aus formalen Gründen eingebaut. Jetzt sehe ich, hier gibt es auch einen Gefahrenübergang bezüglich Concurrency, der mich wahrscheinlich damals bewogen hat „vorsichtshalber“ einen POST zu machen...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<linktarget COLOR="#ac316f" DESTINATION="ID_1174594521" ENDARROW="Default" ENDINCLINATION="-475;-22;" ID="Arrow_ID_358088244" SOURCE="ID_1861186167" STARTARROW="None" STARTINCLINATION="-246;9;"/>
|
||||
<icon BUILTIN="smiley-oh"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1702577323141" ID="ID_599055156" MODIFIED="1702589940778" TEXT="muß deshalb den (nun einzigen) λ-post höher im Callgraphen platzieren">
|
||||
<arrowlink COLOR="#ad0013" DESTINATION="ID_650472693" ENDARROW="Default" ENDINCLINATION="-796;37;" ID="Arrow_ID_1470263046" STARTARROW="None" STARTINCLINATION="193;-386;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue