Work on making Angelscript work threaded
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2021-04-17 13:50:43 +02:00
parent 7dff0c90bc
commit a8f3e30049
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
2 changed files with 37 additions and 8 deletions

View File

@ -98,6 +98,8 @@ void AngelScriptResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg,
} }
_contextPool = new ContextPool(_engine); _contextPool = new ContextPool(_engine);
asPrepareMultithread();
} }
void AngelScriptResolver::RegisterTypes() { void AngelScriptResolver::RegisterTypes() {

View File

@ -2,34 +2,61 @@
#define PKMNLIB_CONTEXTPOOL_HPP #define PKMNLIB_CONTEXTPOOL_HPP
#include <angelscript.h> #include <angelscript.h>
#include <mutex>
#include <thread>
class ContextPool { class ContextPool {
std::vector<asIScriptContext*> _pool; struct CtxThreadedPoolStorage {
std::vector<asIScriptContext*> Pool;
std::mutex Lock;
~CtxThreadedPoolStorage() {
for (auto* ctx : Pool) {
ctx->Release();
}
}
};
ArbUt::Dictionary<std::thread::id, CtxThreadedPoolStorage*> _pool;
asIScriptEngine* _engine; asIScriptEngine* _engine;
CtxThreadedPoolStorage* GetThreadPool() {
auto id = std::this_thread::get_id();
if (!_pool.Has(id)) {
auto t = CtxThreadedPoolStorage();
_pool.Insert(id, new CtxThreadedPoolStorage());
}
return _pool[id];
}
public: public:
ContextPool(asIScriptEngine* engine) : _engine(engine) {} ContextPool(asIScriptEngine* engine) : _engine(engine) {}
~ContextPool() { ~ContextPool() {
for (auto ctx : _pool) { for (const auto& kv : _pool) {
ctx->Release(); delete kv.second;
} }
} }
asIScriptContext* RequestContext() { asIScriptContext* RequestContext() {
// Get a context from the pool, or create a new // Get a context from the pool, or create a new
asIScriptContext* ctx = nullptr; asIScriptContext* ctx = nullptr;
if (!_pool.empty()) { auto* pool = GetThreadPool();
ctx = *_pool.rbegin(); std::lock_guard<std::mutex> guard(pool->Lock);
_pool.pop_back(); if (!pool->Pool.empty()) {
} else ctx = *pool->Pool.rbegin();
pool->Pool.pop_back();
} else {
ctx = _engine->CreateContext(); ctx = _engine->CreateContext();
}
return ctx; return ctx;
} }
void ReturnContextToPool(asIScriptContext* ctx) { void ReturnContextToPool(asIScriptContext* ctx) {
ctx->Unprepare(); ctx->Unprepare();
_pool.push_back(ctx); auto* pool = GetThreadPool();
std::lock_guard<std::mutex> guard(pool->Lock);
pool->Pool.push_back(ctx);
} }
}; };