mcs: refactor finaliseCap to ease verification

This in particular introduces the function
schedContext_unbindReply, which is used within
finaliseCap, as well as invokeSchedContext_Unbind.

Signed-off-by: Michael McInerney <michael.mcinerney@proofcraft.systems>
This commit is contained in:
Michael McInerney 2025-05-06 14:39:47 +09:30 committed by Gerwin Klein
parent 8d569b8e65
commit d16c975677
3 changed files with 29 additions and 13 deletions

View file

@ -64,6 +64,10 @@ void schedContext_donate(sched_context_t *sc, tcb_t *to);
void schedContext_bindNtfn(sched_context_t *sc, notification_t *ntfn);
/* unbind scheduling context from a notification */
void schedContext_unbindNtfn(sched_context_t *sc);
/* unbind notification from a scheduling context */
void schedContextMaybeUnbindNtfn(notification_t *ntfnPtr);
/* unbind scheduling context from a reply */
void schedContext_unbindReply(sched_context_t *sc);
time_t schedContext_updateConsumed(sched_context_t *sc);
void schedContext_completeYieldTo(tcb_t *yielder);

View file

@ -123,7 +123,7 @@ finaliseCap_ret_t finaliseCap(cap_t cap, bool_t final, bool_t exposed)
if (final) {
notification_t *ntfn = NTFN_PTR(cap_notification_cap_get_capNtfnPtr(cap));
#ifdef CONFIG_KERNEL_MCS
schedContext_unbindNtfn(SC_PTR(notification_ptr_get_ntfnSchedContext(ntfn)));
schedContextMaybeUnbindNtfn(ntfn);
#endif
unbindMaybeNotification(ntfn);
cancelAllSignals(ntfn);
@ -137,12 +137,13 @@ finaliseCap_ret_t finaliseCap(cap_t cap, bool_t final, bool_t exposed)
if (final) {
reply_t *reply = REPLY_PTR(cap_reply_cap_get_capReplyPtr(cap));
if (reply && reply->replyTCB) {
switch (thread_state_get_tsType(reply->replyTCB->tcbState)) {
tcb_t *tcb = reply->replyTCB;
switch (thread_state_get_tsType(tcb->tcbState)) {
case ThreadState_BlockedOnReply:
reply_remove(reply, reply->replyTCB);
reply_remove(reply, tcb);
break;
case ThreadState_BlockedOnReceive:
cancelIPC(reply->replyTCB);
cancelIPC(tcb);
break;
default:
fail("Invalid tcb state");
@ -220,11 +221,7 @@ finaliseCap_ret_t finaliseCap(cap_t cap, bool_t final, bool_t exposed)
sched_context_t *sc = SC_PTR(cap_sched_context_cap_get_capSCPtr(cap));
schedContext_unbindAllTCBs(sc);
schedContext_unbindNtfn(sc);
if (sc->scReply) {
assert(call_stack_get_isHead(sc->scReply->replyNext));
sc->scReply->replyNext = call_stack_new(0, false);
sc->scReply = NULL;
}
schedContext_unbindReply(sc);
if (sc->scYieldFrom) {
schedContext_completeYieldTo(sc->scYieldFrom);
}

View file

@ -143,10 +143,7 @@ static exception_t invokeSchedContext_Unbind(sched_context_t *sc)
{
schedContext_unbindAllTCBs(sc);
schedContext_unbindNtfn(sc);
if (sc->scReply) {
sc->scReply->replyNext = call_stack_new(0, false);
sc->scReply = NULL;
}
schedContext_unbindReply(sc);
return EXCEPTION_NONE;
}
@ -398,6 +395,24 @@ void schedContext_unbindNtfn(sched_context_t *sc)
}
}
void schedContextMaybeUnbindNtfn(notification_t *ntfnPtr)
{
sched_context_t *sc = SC_PTR(notification_ptr_get_ntfnSchedContext(ntfnPtr));
if (sc) {
schedContext_unbindNtfn(sc);
}
}
void schedContext_unbindReply(sched_context_t *sc)
{
if (sc && sc->scReply) {
assert(call_stack_get_isHead(sc->scReply->replyNext));
sc->scReply->replyNext = call_stack_new(0, false);
sc->scReply = NULL;
}
}
time_t schedContext_updateConsumed(sched_context_t *sc)
{
ticks_t consumed = sc->scConsumed;