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