More work on thread scheduling and tracebacks
This commit is contained in:
@@ -118,7 +118,6 @@ Tangible *World::tangible_make(lua_State *L, int64_t id, bool pushdb) {
|
||||
|
||||
// Populate the database and metatable with initial stuff.
|
||||
LS.rawset(database, "inventory", LuaNewTable);
|
||||
LS.rawset(database, "id", id);
|
||||
LS.rawset(metatab, "id", id);
|
||||
LS.rawset(metatab, "threads", LuaNewTable);
|
||||
// LS.rawset(metatab, "__metatable", LuaNil);
|
||||
@@ -258,14 +257,13 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
|
||||
}
|
||||
LS.rawset(threads, tid, thread);
|
||||
LS.result();
|
||||
|
||||
|
||||
// Push the thread's ID into the runnable thread queue,
|
||||
// then run the thread queue.
|
||||
thread_sched_.add(0, tid, place_id);
|
||||
run_scheduled_threads(0);
|
||||
}
|
||||
|
||||
|
||||
void World::run_scheduled_threads(int64_t clk) {
|
||||
lua_State *L = state();
|
||||
LuaVar tangibles, place, mt, threads, thread;
|
||||
@@ -293,23 +291,31 @@ void World::run_scheduled_threads(int64_t clk) {
|
||||
|
||||
// Resume the coroutine.
|
||||
lua_State *CO = LS.ckthread(thread);
|
||||
int status = lua_resume(CO, 3);
|
||||
int top = lua_gettop(CO);
|
||||
int status = lua_resume(CO, (top > 0) ? (top - 1) : 0);
|
||||
|
||||
// Three possible outcomes: finished, yielded, or errored.
|
||||
if (status == LUA_YIELD) {
|
||||
// When the wait statement yields, it yields the desired timestamp.
|
||||
std::cerr << "Thread yield top = " << lua_gettop(CO) << std::endl;
|
||||
// TODO: Insert the thread back into thread_sched_.
|
||||
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||
if ((lua_gettop(CO) != 1) || (!lua_isnumber(CO, 1))) {
|
||||
std::cerr << "Thread yielded incorrectly. Killing it." << std::endl;
|
||||
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||
} else {
|
||||
lua_Number delay = lua_tonumber(CO, 1);
|
||||
lua_settop(CO, 0);
|
||||
std::cerr << "Thread wait = " << delay << std::endl;
|
||||
thread_sched_.add(sched.clock() + int64_t(delay), sched.thread_id(), sched.place_id());
|
||||
std::cerr << "Added to schedule." << std::endl;
|
||||
}
|
||||
} else if (status == 0) {
|
||||
// Successfully ran to completion. Remove from thread table.
|
||||
std::cerr << "Thread ran to completion." << std::endl;
|
||||
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||
} else {
|
||||
// Transfer the error message from CO to L, and add a traceback.
|
||||
// Generated an error. Add a traceback, print, and kill the coroutine.
|
||||
traceback_coroutine(CO);
|
||||
std::cerr << lua_tostring(CO, -1);
|
||||
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||
traceback_coroutine(L, CO);
|
||||
std::cerr << lua_tostring(L, -1);
|
||||
}
|
||||
}
|
||||
LS.result();
|
||||
@@ -330,3 +336,10 @@ LuaDefine(tangible_make, "c") {
|
||||
World::fetch(L)->tangible_make(L, 0, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LuaDefine(world_wait, "f") {
|
||||
if (lua_type(L, -1) != LUA_TNUMBER) {
|
||||
luaL_error(L, "Argument to wait must be a number.");
|
||||
}
|
||||
return lua_yield(L, 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user