コード例 #1
0
ファイル: thread_dpool.c プロジェクト: dilshod/luasys
/*
 * 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
ファイル: thread_dpool.c プロジェクト: LuaDist/luasys
/*
 * Arguments: dpool_udata, data_items (any) ...
 */
static int
dpool_put (lua_State *L)
{
    struct sys_thread *td = sys_get_thread();
    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_pushlightuserdata(L, (void *) DPOOL_PUTONFULL);
	    lua_rawget(L, 1);
	    lua_insert(L, 2);
	    lua_call(L, 1 + nput, LUA_MULTRET);
	    nput = lua_gettop(L) - 1;
	    if (!nput) return 0;
	} else do {
	    if (thread_event_wait(&dp->tev, TIMEOUT_INFINITE))
		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);
	thread_yield(L);
	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;

	/* notify event_queue */
	if (!dp->n++ && dp->trigger)
	    sys_trigger_notify(&dp->trigger, SYS_EVREAD);

	thread_event_signal(&dp->tev);
    }
    return 0;
}
コード例 #3
0
ファイル: test.c プロジェクト: annidy/simplethread
static void
func(void * p) {
	struct args * arg = p;
	if (arg->wait) {
		thread_event_wait(arg->wait);
	}
	printf("n = %d\n", arg->n);
	if (arg->trigger) {
		thread_event_trigger(arg->trigger);
	}
}
コード例 #4
0
ファイル: thread_dpool.c プロジェクト: LuaDist/luasys
/*
 * Arguments: dpool_udata, [timeout (milliseconds)]
 * Returns: [signalled/timedout (boolean)]
 */
static int
dpool_wait (lua_State *L)
{
    struct data_pool *dp = checkudata(L, 1, DPOOL_TYPENAME);
    const msec_t timeout = lua_isnoneornil(L, 2)
     ? TIMEOUT_INFINITE : (msec_t) lua_tointeger(L, 2);
    int res;

    res = thread_event_wait(&dp->tev, timeout);
    if (res >= 0) {
	lua_pushboolean(L, !res);
	return 1;
    }
    return sys_seterror(L, 0);
}
コード例 #5
0
ファイル: ltask.c プロジェクト: 4Second2None/ltask
static void
worker_func(void *p) {
	struct worker *w = p;
	for (;;) {
		w->suspend = 0;
		while (run_slice(w)) {
			struct workshop * ws = w->workshop;
			int i;
			for (i=0;i<ws->threads;i++) {
				struct worker *w = &ws->w[i];
				if (w->suspend) {
					thread_event_trigger(&w->event);
				}
			}
		}
		w->suspend = 1;
		thread_event_wait(&w->event);
	}
}
コード例 #6
0
ファイル: thread_dpool.c プロジェクト: LuaDist/luasys
/*
 * Arguments: dpool_udata, [timeout (milliseconds)]
 * Returns: data_items (any) ...
 */
static int
dpool_get (lua_State *L)
{
    struct data_pool *dp = checkudata(L, 1, DPOOL_TYPENAME);
    const msec_t timeout = lua_isnoneornil(L, 2)
     ? TIMEOUT_INFINITE : (msec_t) lua_tointeger(L, 2);
    int nput;

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

    if ((dp->flags & DPOOL_GETONEMPTY) && !dp->n) {
	lua_pushlightuserdata(L, (void *) DPOOL_GETONEMPTY);
	lua_rawget(L, 1);
	lua_insert(L, 2);
	lua_call(L, 1, LUA_MULTRET);
	nput = lua_gettop(L) - 1;
	if (nput) return nput;
    }

    for (; ; ) {
	/* get from storage */
	if (dp->n) {
	    const int idx = dp->idx + 1;
	    int i;

	    lua_rawgeti(L, 1, idx);
	    nput = lua_tointeger(L, -1);
	    lua_pushnil(L);
	    lua_rawseti(L, 1, idx);
	    dp->idx = idx + nput;
	    for (i = dp->idx; i > idx; --i) {
		lua_rawgeti(L, 1, i);
		lua_pushnil(L);
		lua_rawseti(L, 1, i);
	    }
	    if (dp->idx == dp->top)
		dp->idx = dp->top = 0;
	    if (dp->n-- == dp->max) {
		/* notify event_queue */
		if (dp->trigger)
		    sys_trigger_notify(&dp->trigger, SYS_EVWRITE);
		thread_event_signal(&dp->tev);
	    }
	    return nput;
	}

	/* wait signal */
	{
	    int res;
	    dp->nwaits++;
	    res = thread_event_wait(&dp->tev, timeout);
	    dp->nwaits--;
	    if (res) {
		if (res == 1) {
		    lua_pushboolean(L, 0);
		    return 1;  /* timed out */
		}
		return sys_seterror(L, 0);
	    }
	}

	/* get directly from another thread */
	nput = dp->nput;
	if (nput) {
	    dp->nput = 0;
	    lua_xmove(dp->td->L, L, nput);
	    return nput;
	}
    }
}