Пример #1
0
/*
 * Arguments: dpool_udata, data_items (any) ...
 */
static int
dpool_put (lua_State *L)
{
    struct sys_thread *td = sys_thread_get();
    struct data_pool *dp = checkudata(L, 1, DPOOL_TYPENAME);
    int nput = lua_gettop(L) - 1;

    if (!td) luaL_argerror(L, 0, "Threading not initialized");
    if (!nput) luaL_argerror(L, 2, "data expected");

    lua_getfenv(L, 1);  /* storage */
    lua_insert(L, 1);

    if (dp->n >= dp->max) {
	if (dp->flags & DPOOL_PUTONFULL) {
	    lua_rawgetp(L, 1, (void *) DPOOL_PUTONFULL);
	    lua_insert(L, 2);
	    lua_call(L, 1 + nput, LUA_MULTRET);
	    nput = lua_gettop(L) - 1;
	    if (!nput) return 0;
	} else {
	    do {
		const int res = thread_event_wait(&dp->tev, td,
		 TIMEOUT_INFINITE);

		sys_thread_check(td);
		if (res) return sys_seterror(L, 0);
	    } while (dp->n >= dp->max);
	}
    }

    /* Try directly move data between threads */
    if (dp->nwaits && !dp->td) {
	dp->td = td;
	dp->nput = nput;
	thread_event_signal(&dp->tev);
	sys_thread_switch(0);
	dp->td = NULL;
	if (!dp->nput) return 0;  /* moved to thread */
	dp->nput = 0;
    }

    /* Keep data in the storage */
    {
	int top = dp->top;

	lua_pushinteger(L, nput);
	do {
	    lua_rawseti(L, 1, ++top);
	} while (nput--);
	dp->top = top;

	if (!dp->n++) {
	    thread_event_signal(&dp->tev);
	}
    }
    return 0;
}
Пример #2
0
PUBLIC
void
Thread_object::invoke(L4_obj_ref /*self*/, L4_fpage::Rights rights, Syscall_frame *f, Utcb *utcb)
{
  register L4_obj_ref::Operation op = f->ref().op();
  if (((op != 0) && !(op & L4_obj_ref::Ipc_send))
      || (op & L4_obj_ref::Ipc_reply)
      || f->tag().proto() != L4_msg_tag::Label_thread)
    {
      /* we do IPC */
      Thread *ct = current_thread();
      Thread *sender = 0;
      Thread *partner = 0;
      bool have_rcv = false;

      if (EXPECT_FALSE(!check_sys_ipc(op, &partner, &sender, &have_rcv)))
	{
	  utcb->error = L4_error::Not_existent;
	  return;
	}

      ct->do_ipc(f->tag(), partner, partner, have_rcv, sender,
                 f->timeout(), f, rights);
      return;
    }

  switch (utcb->values[0] & Opcode_mask)
    {
    case Op_control:
      f->tag(sys_control(rights, f->tag(), utcb));
      return;
    case Op_ex_regs:
      f->tag(sys_ex_regs(f->tag(), utcb));
      return;
    case Op_switch:
      f->tag(sys_thread_switch(f->tag(), utcb));
      return;
    case Op_stats:
      f->tag(sys_thread_stats(f->tag(), utcb));
      return;
    case Op_vcpu_resume:
      f->tag(sys_vcpu_resume(f->tag(), utcb));
      return;
    case Op_register_del_irq:
      f->tag(sys_register_delete_irq(f->tag(), utcb, utcb));
      return;
    case Op_modify_senders:
      f->tag(sys_modify_senders(f->tag(), utcb, utcb));
      return;
    case Op_vcpu_control:
      f->tag(sys_vcpu_control(rights, f->tag(), utcb));
      return;
    default:
      f->tag(invoke_arch(f->tag(), utcb));
      return;
    }
}
Пример #3
0
static int
thread_switch_wrap (lua_State *L)
{
  struct sys_thread *td = sys_thread_get();

  (void) L;

  if (td) {
    sys_thread_switch(td);
    sys_thread_check(td, L);
  }
  return 0;
}