int TenshiRunQuanta(TenshiRuntimeState s) { int ops_left = QUANTA_OPCODES; while (ops_left > 0) { TenshiActorState a; int ret = ActorDequeueHead(s, &a); if (ret != LUA_OK) return ret; if (!a) { printf("NOTHING TO RUN!\n"); return LUA_OK; } ret = threading_run_ops(a->L, ops_left, &ops_left); if (ret == THREADING_ERROR) { printf("THERE WAS AN ERROR!\n"); const char *msg = lua_tostring(a->L, -1); if (msg) /* is error object a string? */ luaL_traceback(a->L, a->L, msg, 0); /* use standard traceback */ else if (!lua_isnoneornil(a->L, -1)) { /* non-string error object? */ /* try its 'tostring' metamethod */ if (!luaL_callmeta(a->L, -1, "__tostring")) lua_pushliteral(a->L, "(no error message)"); } /* else no error object, does nothing */ const char *err_w_traceback = lua_tostring(a->L, -1); printf("%s\n", err_w_traceback); return LUA_ERRRUN; } if (ret == THREADING_EXITED) { printf("Thread exited!\n"); ActorDestroy(a); } else if (ret == THREADING_YIELD) { printf("Thread yielded (blocked)!\n"); ret = ActorSetBlocked(a); if (ret != LUA_OK) return ret; } else if (ret == THREADING_PREEMPT) { // Requeue it printf("Thread preempted!\n"); ret = ActorSetRunnable(a, 0); if (ret != LUA_OK) return ret; } } return LUA_OK; }
int TenshiRunQuanta(TenshiRuntimeState s) { // Do timeouts ActorProcessTimeouts(s); // Run the sensor actor // Dup the function first, as it disappears when we exit // TODO(rqou): Will we have a problem with the hardcoded op limit? lua_pushvalue(s->sensor_actor->L, -1); int ret = threading_run_ops(s->sensor_actor->L, 1000, NULL); if (ret != THREADING_EXITED) { printf("There was an error running the sensor actor!\n"); print_traceback(s->sensor_actor->L); return ret; } // Run the main code int ops_left = QUANTA_OPCODES; while (ops_left > 0) { TenshiActorState a; ret = ActorDequeueHead(s, &a); if (ret != LUA_OK) return ret; if (!a) { break; } ret = threading_run_ops(a->L, ops_left, &ops_left); if (ret == THREADING_ERROR) { printf("THERE WAS AN ERROR!\n"); print_traceback(a->L); return LUA_ERRRUN; } if (ret == THREADING_EXITED) { printf("Thread exited!\n"); ActorDestroy(a); } else if (ret == THREADING_YIELD) { printf("Thread yielded (blocked)!\n"); ret = ActorSetBlocked(a); if (ret != LUA_OK) return ret; } else if (ret == THREADING_PREEMPT) { // Requeue it ret = ActorSetRunnable(a, 0); if (ret != LUA_OK) return ret; } } // Run the actuator actor // Dup the function first, as it disappears when we exit lua_pushvalue(s->actuator_actor->L, -1); ret = threading_run_ops(s->actuator_actor->L, 1000, NULL); if (ret != THREADING_EXITED) { printf("There was an error running the actuator actor!\n"); print_traceback(s->actuator_actor->L); return ret; } lua_gc(s->L, LUA_GCCOLLECT, 0); return LUA_OK; }