PRIVATE void Thread::ipc_send_msg(Receiver *recv) { Syscall_frame *regs = _snd_regs; bool success = transfer_msg(regs->tag(), nonull_static_cast<Thread*>(recv), regs, _ipc_send_rights); sender_dequeue(recv->sender_list()); recv->vcpu_update_state(); //printf(" done\n"); regs->tag(L4_msg_tag(regs->tag(), success ? 0 : L4_msg_tag::Error)); Mword state_del = Thread_ipc_mask | Thread_ipc_transfer; Mword state_add = Thread_ready; if (Receiver::prepared()) // same as in Receiver::prepare_receive_dirty_2 state_add |= Thread_receive_wait; if (cpu() == current_cpu()) { state_change_dirty(~state_del, state_add); if (current_sched()->deblock(cpu(), current_sched(), true)) recv->switch_to_locked(this); } else { drq_state_change(~state_del, state_add); current()->schedule_if(current()->handle_drq()); } }
bool Sched_context::Ready_queue::deblock(Sched_context *sc, Sched_context *crs, bool lazy_q) { assert(cpu_lock.test()); Sched_context *cs = current_sched(); bool res = true; if (sc == cs) { if (crs && crs->dominates(sc)) res = false; } else { deblock_refill(sc); if ((EXPECT_TRUE(cs != 0) && cs->dominates(sc)) || (crs && crs->dominates(sc))) res = false; } if (res && lazy_q) return true; ready_enqueue(sc); return res; }