void doReplyTransfer(tcb_t *sender, tcb_t *receiver, cte_t *slot) { assert(thread_state_get_tsType(receiver->tcbState) == ThreadState_BlockedOnReply); if (likely(fault_get_faultType(receiver->tcbFault) == fault_null_fault)) { doIPCTransfer(sender, NULL, 0, true, receiver, false); /** GHOSTUPD: "(True, gs_set_assn cteDeleteOne_'proc (ucast cap_reply_cap))" */ setThreadState(receiver, ThreadState_Running); attemptSwitchTo(receiver); } else { bool_t restart; /** GHOSTUPD: "(True, gs_set_assn cteDeleteOne_'proc (ucast cap_reply_cap))" */ restart = handleFaultReply(receiver, sender); fault_null_fault_ptr_new(&receiver->tcbFault); if (restart) { setThreadState(receiver, ThreadState_Restart); attemptSwitchTo(receiver); } else { setThreadState(receiver, ThreadState_Inactive); } } finaliseCap(slot->cap, true, true); slot->cap = cap_null_cap_new(); }
void ipcCancel(tcb_t *tptr) { thread_state_t *state = &tptr->tcbState; switch (thread_state_ptr_get_tsType(state)) { case ThreadState_BlockedOnSend: case ThreadState_BlockedOnReceive: { /* blockedIPCCancel state */ endpoint_t *epptr; tcb_queue_t queue; epptr = EP_PTR(thread_state_ptr_get_blockingIPCEndpoint(state)); /* Haskell error "blockedIPCCancel: endpoint must not be idle" */ assert(endpoint_ptr_get_state(epptr) != EPState_Idle); /* Dequeue TCB */ queue = ep_ptr_get_queue(epptr); queue = tcbEPDequeue(tptr, queue); ep_ptr_set_queue(epptr, queue); if (!queue.head) { endpoint_ptr_set_state(epptr, EPState_Idle); } setThreadState(tptr, ThreadState_Inactive); break; } case ThreadState_BlockedOnAsyncEvent: asyncIPCCancel(tptr, AEP_PTR(thread_state_ptr_get_blockingIPCEndpoint(state))); break; case ThreadState_BlockedOnReply: { cte_t *slot, *callerCap; fault_null_fault_ptr_new(&tptr->tcbFault); /* Get the reply cap slot */ slot = TCB_PTR_CTE_PTR(tptr, tcbReply); callerCap = CTE_PTR(cap_reply_cap_get_capCallerSlot(slot->cap)); if (callerCap) { finaliseCap(callerCap->cap, true, true); callerCap->cap = cap_null_cap_new(); } cap_reply_cap_ptr_set_capCallerSlot(&slot->cap, CTE_REF(NULL)); break; } } }
void deleteCallerCap(tcb_t *receiver) { cte_t *callerSlot; callerSlot = TCB_PTR_CTE_PTR(receiver, tcbCaller); if (cap_get_capType(callerSlot->cap) == cap_reply_cap) { finaliseCap(callerSlot->cap, true, true); callerSlot->cap = cap_null_cap_new(); } }