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))" */ cteDeleteOne(slot); setThreadState(receiver, ThreadState_Running); attemptSwitchTo(receiver); } else { bool_t restart; /** GHOSTUPD: "(True, gs_set_assn cteDeleteOne_'proc (ucast cap_reply_cap))" */ cteDeleteOne(slot); restart = handleFaultReply(receiver, sender); fault_null_fault_ptr_new(&receiver->tcbFault); if (restart) { setThreadState(receiver, ThreadState_Restart); attemptSwitchTo(receiver); } else { setThreadState(receiver, ThreadState_Inactive); } } }
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); setThreadState(receiver, ThreadState_Running); attemptSwitchTo(receiver); } else { bool_t restart; restart = handleFaultReply(receiver, sender); fault_null_fault_ptr_new(&receiver->tcbFault); if (restart) { setThreadState(receiver, ThreadState_Restart); attemptSwitchTo(receiver); } else { setThreadState(receiver, ThreadState_Inactive); } } if (cap_reply_cap_get_capInCDT(slot->cap)) { cte_t *replySlot = TCB_PTR_CTE_PTR(receiver, tcbReply); assert(cap_get_capType(replySlot->cap) == cap_reply_cap); assert(cap_reply_cap_get_capInCDT(replySlot->cap)); cdtRemove(replySlot); cdtRemove(slot); slot->cap = cap_null_cap_new(); replySlot->cap = cap_reply_cap_new(false, true, TCB_REF(NULL)); } else { deleteCallerCap(sender); } }
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); setThreadState(receiver, ThreadState_Running); attemptSwitchTo(receiver); } else { bool_t restart; 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 sendIPC(bool_t blocking, bool_t do_call, word_t badge, bool_t canGrant, tcb_t *thread, endpoint_t *epptr) { //printf("\n===in sendIPC funtion==\n"); switch (endpoint_ptr_get_state(epptr)) { case EPState_Idle: //printf("in case idle\n"); case EPState_Send: //printf("in case send\n"); if (blocking) { tcb_queue_t queue; /* Set thread state to BlockedOnSend */ thread_state_ptr_set_tsType(&thread->tcbState, ThreadState_BlockedOnSend); thread_state_ptr_set_blockingIPCEndpoint( &thread->tcbState, EP_REF(epptr)); thread_state_ptr_set_blockingIPCBadge( &thread->tcbState, badge); thread_state_ptr_set_blockingIPCCanGrant( &thread->tcbState, canGrant); thread_state_ptr_set_blockingIPCIsCall( &thread->tcbState, do_call); scheduleTCB(thread); /* Place calling thread in endpoint queue */ queue = ep_ptr_get_queue(epptr); queue = tcbEPAppend(thread, queue); endpoint_ptr_set_state(epptr, EPState_Send); ep_ptr_set_queue(epptr, queue); } break; case EPState_Recv: { tcb_queue_t queue; tcb_t *dest; bool_t diminish; //printf("in case recv\n"); /* Get the head of the endpoint queue. */ queue = ep_ptr_get_queue(epptr); dest = queue.head; /* Haskell error "Receive endpoint queue must not be empty" */ assert(dest); /* Dequeue the first TCB */ queue = tcbEPDequeue(dest, queue); ep_ptr_set_queue(epptr, queue); if (!queue.head) { endpoint_ptr_set_state(epptr, EPState_Idle); } /* Do the transfer */ diminish = thread_state_get_blockingIPCDiminishCaps(dest->tcbState); doIPCTransfer(thread, epptr, badge, canGrant, dest, diminish); setThreadState(dest, ThreadState_Running); attemptSwitchTo(dest); //printf("the dest thread's prio is %d\n", dest->tcbPriority); if (do_call || fault_ptr_get_faultType(&thread->tcbFault) != fault_null_fault) { if (canGrant && !diminish) { setupCallerCap(thread, dest); } else { setThreadState(thread, ThreadState_Inactive); } } break; } } }
void sendIPC(bool_t blocking, bool_t do_call, word_t badge, bool_t canGrant, tcb_t *thread, endpoint_t *epptr) { switch (endpoint_ptr_get_state(epptr)) { case EPState_Idle: case EPState_Send: if (blocking) { tcb_queue_t queue; /* Set thread state to BlockedOnSend */ thread_state_ptr_set_tsType(&thread->tcbState, ThreadState_BlockedOnSend); thread_state_ptr_set_blockingObject( &thread->tcbState, EP_REF(epptr)); thread_state_ptr_set_blockingIPCBadge( &thread->tcbState, badge); thread_state_ptr_set_blockingIPCCanGrant( &thread->tcbState, canGrant); thread_state_ptr_set_blockingIPCIsCall( &thread->tcbState, do_call); scheduleTCB(thread); /* Place calling thread in endpoint queue */ queue = ep_ptr_get_queue(epptr); queue = tcbEPAppend(thread, queue); endpoint_ptr_set_state(epptr, EPState_Send); ep_ptr_set_queue(epptr, queue); } break; case EPState_Recv: { tcb_queue_t queue; tcb_t *dest; /* Get the head of the endpoint queue. */ queue = ep_ptr_get_queue(epptr); dest = queue.head; /* Haskell error "Receive endpoint queue must not be empty" */ assert(dest); /* Dequeue the first TCB */ queue = tcbEPDequeue(dest, queue); ep_ptr_set_queue(epptr, queue); if (!queue.head) { endpoint_ptr_set_state(epptr, EPState_Idle); } /* Do the transfer */ doIPCTransfer(thread, epptr, badge, canGrant, dest); setThreadState(dest, ThreadState_Running); attemptSwitchTo(dest); if (do_call || seL4_Fault_ptr_get_seL4_FaultType(&thread->tcbFault) != seL4_Fault_NullFault) { if (canGrant) { setupCallerCap(thread, dest); } else { setThreadState(thread, ThreadState_Inactive); } } break; } } }