示例#1
0
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();
    }
}
示例#2
0
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);
}