void Ipc_sender<Derived>::send_msg(Receiver *receiver) { set_receiver(receiver); if (!Config::Irq_shortcut) { // in profile mode, don't optimize // in non-profile mode, enqueue _after_ shortcut if still necessary sender_enqueue(receiver->sender_list(), 255); receiver->vcpu_set_irq_pending(); } // if the thread is waiting for this interrupt, make it ready; // this will cause it to run irq->receiver_ready(), which // handles the rest // XXX careful! This code may run in midst of an do_ipc() // operation (or similar)! if (Receiver::Rcv_state s = receiver->sender_ok(this)) { Syscall_frame *dst_regs = derived()->transfer_msg(receiver); if (derived()->requeue_sender()) { sender_enqueue(receiver->sender_list(), 255); receiver->vcpu_set_irq_pending(); } // ipc completed receiver->state_change_dirty(~Thread_ipc_mask, 0); // in case a timeout was set receiver->reset_timeout(); if (s == Receiver::Rs_ipc_receive) { if (handle_shortcut(dst_regs, receiver)) return; } // we don't need to manipulate the state in a safe way // because we are still running with interrupts turned off receiver->state_add_dirty(Thread_ready); receiver->sched()->deblock(receiver->cpu()); return; } if (Config::Irq_shortcut) { // in profile mode, don't optimize // in non-profile mode, enqueue after shortcut if still necessary sender_enqueue(receiver->sender_list(), 255); receiver->vcpu_set_irq_pending(); } }
void Sender::sender_update_prio(P_LIST list, unsigned short newprio) { if(EXPECT_FALSE(sender_prio() == newprio)) return; Lock_guard<Cpu_lock> guard (&cpu_lock); if (!in_sender_list()) return; sender_dequeue(list); sender_enqueue(list, newprio); }