Added class Schedule for threads
This commit is contained in:
@@ -9,6 +9,7 @@ CPP_FILES=\
|
|||||||
cpp/luaconsole.cpp\
|
cpp/luaconsole.cpp\
|
||||||
cpp/idalloc.cpp\
|
cpp/idalloc.cpp\
|
||||||
cpp/globaldb.cpp\
|
cpp/globaldb.cpp\
|
||||||
|
cpp/sched.cpp\
|
||||||
cpp/table.cpp\
|
cpp/table.cpp\
|
||||||
cpp/gui.cpp\
|
cpp/gui.cpp\
|
||||||
cpp/luasnap.cpp\
|
cpp/luasnap.cpp\
|
||||||
|
|||||||
27
luprex/core/cpp/sched.cpp
Normal file
27
luprex/core/cpp/sched.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
#include "sched.hpp"
|
||||||
|
|
||||||
|
bool SchedEntry::operator < (const SchedEntry &other) const {
|
||||||
|
if (clock_ < other.clock_) return true;
|
||||||
|
if (clock_ > other.clock_) return false;
|
||||||
|
if (thread_id_ < other.thread_id_) return true;
|
||||||
|
if (thread_id_ > other.thread_id_) return false;
|
||||||
|
if (place_id_ < other.place_id_) return true;
|
||||||
|
if (place_id_ > other.place_id_) return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Schedule::add(int64_t clk, int64_t thid, int64_t plid) {
|
||||||
|
schedule_.insert(SchedEntry(clk, thid, plid));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Schedule::ready(int64_t clk) const {
|
||||||
|
return (!schedule_.empty()) && (schedule_.begin()->clock() <= clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
SchedEntry Schedule::pop() {
|
||||||
|
SchedEntry result = *schedule_.begin();
|
||||||
|
schedule_.erase(schedule_.begin());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
39
luprex/core/cpp/sched.hpp
Normal file
39
luprex/core/cpp/sched.hpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef SCHED_HPP
|
||||||
|
#define SCHED_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
class SchedEntry {
|
||||||
|
private:
|
||||||
|
friend class Schedule;
|
||||||
|
|
||||||
|
int64_t clock_;
|
||||||
|
int64_t thread_id_;
|
||||||
|
int64_t place_id_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int64_t clock() const { return clock_; }
|
||||||
|
int64_t thread_id() const { return thread_id_; }
|
||||||
|
int64_t place_id() const { return place_id_; }
|
||||||
|
|
||||||
|
SchedEntry(int64_t clk, int64_t thid, int64_t plid) {
|
||||||
|
clock_ = clk;
|
||||||
|
thread_id_ = thid;
|
||||||
|
place_id_ = plid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator < (const SchedEntry &other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Schedule {
|
||||||
|
private:
|
||||||
|
std::set<SchedEntry> schedule_;
|
||||||
|
public:
|
||||||
|
void add(int64_t clk, int64_t thid, int64_t plid);
|
||||||
|
bool ready(int64_t clk) const;
|
||||||
|
SchedEntry pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SCHED_HPP
|
||||||
|
|
||||||
@@ -261,39 +261,34 @@ void World::invoke_plan(int64_t actor_id, int64_t place_id, const std::string &a
|
|||||||
|
|
||||||
// Push the thread's ID into the runnable thread queue,
|
// Push the thread's ID into the runnable thread queue,
|
||||||
// then run the thread queue.
|
// then run the thread queue.
|
||||||
enqueue_thread(tid, place_id);
|
thread_sched_.add(0, tid, place_id);
|
||||||
run_thread_queue();
|
run_scheduled_threads(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::enqueue_thread(int64_t tid, int64_t place_id) {
|
|
||||||
thread_queue_.insert(std::make_pair(tid, place_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void World::run_thread(int64_t tid, int64_t place_id) {
|
void World::run_scheduled_threads(int64_t clk) {
|
||||||
lua_State *L = state();
|
lua_State *L = state();
|
||||||
LuaVar tangibles, place, mt, threads, thread;
|
LuaVar tangibles, place, mt, threads, thread;
|
||||||
LuaStack LS(L, tangibles, place, mt, threads, thread);
|
LuaStack LS(L, tangibles, place, mt, threads, thread);
|
||||||
|
|
||||||
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
LS.rawget(tangibles, LuaRegistry, "tangibles");
|
||||||
LS.rawget(place, tangibles, place_id);
|
|
||||||
|
while (thread_sched_.ready(clk)) {
|
||||||
|
SchedEntry sched = thread_sched_.pop();
|
||||||
|
LS.rawget(place, tangibles, sched.place_id());
|
||||||
if (!LS.istable(place)) {
|
if (!LS.istable(place)) {
|
||||||
LS.result();
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
LS.getmetatable(mt, place);
|
LS.getmetatable(mt, place);
|
||||||
if (!LS.istable(mt)) {
|
if (!LS.istable(mt)) {
|
||||||
LS.result();
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
LS.rawget(threads, mt, "threads");
|
LS.rawget(threads, mt, "threads");
|
||||||
if (!LS.istable(threads)) {
|
if (!LS.istable(threads)) {
|
||||||
LS.result();
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
LS.rawget(thread, threads, tid);
|
LS.rawget(thread, threads, sched.thread_id());
|
||||||
if (!LS.isthread(thread)) {
|
if (!LS.isthread(thread)) {
|
||||||
LS.result();
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resume the coroutine.
|
// Resume the coroutine.
|
||||||
@@ -304,30 +299,22 @@ void World::run_thread(int64_t tid, int64_t place_id) {
|
|||||||
if (status == LUA_YIELD) {
|
if (status == LUA_YIELD) {
|
||||||
// When the wait statement yields, it yields the desired timestamp.
|
// When the wait statement yields, it yields the desired timestamp.
|
||||||
std::cerr << "Thread yield top = " << lua_gettop(CO) << std::endl;
|
std::cerr << "Thread yield top = " << lua_gettop(CO) << std::endl;
|
||||||
LS.rawset(threads, tid, LuaNil);
|
// TODO: Insert the thread back into thread_sched_.
|
||||||
|
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||||
} else if (status == 0) {
|
} else if (status == 0) {
|
||||||
// Successfully ran to completion. Remove from thread table.
|
// Successfully ran to completion. Remove from thread table.
|
||||||
std::cerr << "Thread ran to completion." << std::endl;
|
std::cerr << "Thread ran to completion." << std::endl;
|
||||||
LS.rawset(threads, tid, LuaNil);
|
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||||
} else {
|
} else {
|
||||||
// Transfer the error message from CO to L, and add a traceback.
|
// Transfer the error message from CO to L, and add a traceback.
|
||||||
LS.rawset(threads, tid, LuaNil);
|
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||||
traceback_coroutine(L, CO);
|
traceback_coroutine(L, CO);
|
||||||
std::cerr << lua_tostring(L, -1);
|
std::cerr << lua_tostring(L, -1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
LS.result();
|
LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::run_thread_queue() {
|
|
||||||
while (!thread_queue_.empty()) {
|
|
||||||
auto iter = thread_queue_.begin();
|
|
||||||
int64_t tid = iter->first;
|
|
||||||
int64_t place_id = iter->second;
|
|
||||||
run_thread(tid, place_id);
|
|
||||||
thread_queue_.erase(iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LuaDefine(tangible_get, "c") {
|
LuaDefine(tangible_get, "c") {
|
||||||
LuaArg id;
|
LuaArg id;
|
||||||
LuaRet database;
|
LuaRet database;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "planemap.hpp"
|
#include "planemap.hpp"
|
||||||
#include "idalloc.hpp"
|
#include "idalloc.hpp"
|
||||||
#include "animqueue.hpp"
|
#include "animqueue.hpp"
|
||||||
|
#include "sched.hpp"
|
||||||
#include "source.hpp"
|
#include "source.hpp"
|
||||||
#include "gui.hpp"
|
#include "gui.hpp"
|
||||||
#include "luasnap.hpp"
|
#include "luasnap.hpp"
|
||||||
@@ -46,10 +47,6 @@ public:
|
|||||||
|
|
||||||
class World {
|
class World {
|
||||||
public:
|
public:
|
||||||
// A thread ID appended to a place ID.
|
|
||||||
//
|
|
||||||
using ThreadPair = std::pair<int64_t, int64_t>;
|
|
||||||
|
|
||||||
// A lua intepreter with snapshot function.
|
// A lua intepreter with snapshot function.
|
||||||
//
|
//
|
||||||
LuaSnap lua_snap_;
|
LuaSnap lua_snap_;
|
||||||
@@ -64,14 +61,12 @@ public:
|
|||||||
PlaneMap plane_map_;
|
PlaneMap plane_map_;
|
||||||
std::unordered_map<int64_t, Tangible> tangibles_;
|
std::unordered_map<int64_t, Tangible> tangibles_;
|
||||||
|
|
||||||
// Thread queue.
|
// Thread schedule: should include every thread, except
|
||||||
|
// for the one currently-executing thread.
|
||||||
//
|
//
|
||||||
std::set<ThreadPair> thread_queue_;
|
Schedule thread_sched_;
|
||||||
|
|
||||||
void enqueue_thread(int64_t tid, int64_t place_id);
|
|
||||||
void run_thread_queue();
|
|
||||||
void run_thread(int64_t tid, int64_t place_id);
|
|
||||||
|
|
||||||
|
void run_scheduled_threads(int64_t clk);
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user