mirror of
https://github.com/OpenMW/openmw.git
synced 2025-05-19 19:11:28 +00:00
New setting "lua num threads". Thread syncronization is changed from std:🧵:yield to std::condition_variable.
This commit is contained in:
parent
a8f76260bc
commit
403d31313c
5 changed files with 107 additions and 30 deletions
|
@ -1,6 +1,6 @@
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <condition_variable>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -830,6 +830,82 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mLuaManager->init();
|
mLuaManager->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OMW::Engine::LuaWorker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit LuaWorker(Engine* engine) :
|
||||||
|
mEngine(engine),
|
||||||
|
mSeparateThread(Settings::Manager::getInt("lua num threads", "Lua") > 0)
|
||||||
|
{
|
||||||
|
if (mSeparateThread)
|
||||||
|
mThread = std::thread([this]{ threadBody(); });
|
||||||
|
};
|
||||||
|
|
||||||
|
void allowUpdate(double dt)
|
||||||
|
{
|
||||||
|
mDt = dt;
|
||||||
|
if (!mSeparateThread)
|
||||||
|
return;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(mMutex);
|
||||||
|
mUpdateRequest = true;
|
||||||
|
}
|
||||||
|
mCV.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void finishUpdate()
|
||||||
|
{
|
||||||
|
if (mSeparateThread)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(mMutex);
|
||||||
|
mCV.wait(lk, [&]{ return !mUpdateRequest; });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
update();
|
||||||
|
mEngine->mLuaManager->applyQueuedChanges();
|
||||||
|
};
|
||||||
|
|
||||||
|
void join()
|
||||||
|
{
|
||||||
|
if (mSeparateThread)
|
||||||
|
mThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
const auto& viewer = mEngine->mViewer;
|
||||||
|
const osg::Timer_t frameStart = viewer->getStartTick();
|
||||||
|
const unsigned int frameNumber = viewer->getFrameStamp()->getFrameNumber();
|
||||||
|
ScopedProfile<UserStatsType::Lua> profile(frameStart, frameNumber, *osg::Timer::instance(), *viewer->getViewerStats());
|
||||||
|
|
||||||
|
mEngine->mLuaManager->update(mEngine->mEnvironment.getWindowManager()->isGuiMode(), mDt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void threadBody()
|
||||||
|
{
|
||||||
|
while (!mEngine->mViewer->done() && !mEngine->mEnvironment.getStateManager()->hasQuitRequest())
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(mMutex);
|
||||||
|
mCV.wait(lk, [&]{ return mUpdateRequest; });
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
|
mUpdateRequest = false;
|
||||||
|
lk.unlock();
|
||||||
|
mCV.notify_one();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine* mEngine;
|
||||||
|
const bool mSeparateThread;
|
||||||
|
std::mutex mMutex;
|
||||||
|
std::condition_variable mCV;
|
||||||
|
bool mUpdateRequest;
|
||||||
|
double mDt = 0;
|
||||||
|
std::thread mThread;
|
||||||
|
};
|
||||||
|
|
||||||
// Initialise and enter main loop.
|
// Initialise and enter main loop.
|
||||||
void OMW::Engine::go()
|
void OMW::Engine::go()
|
||||||
{
|
{
|
||||||
|
@ -912,27 +988,7 @@ void OMW::Engine::go()
|
||||||
mEnvironment.getWindowManager()->executeInConsole(mStartupScript);
|
mEnvironment.getWindowManager()->executeInConsole(mStartupScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start Lua scripting thread
|
LuaWorker luaWorker(this); // starts a separate lua thread if "lua num threads" > 0
|
||||||
std::atomic_bool luaUpdateRequest;
|
|
||||||
double luaDt = 0;
|
|
||||||
std::thread scriptingThread([&]() {
|
|
||||||
const osg::Timer* const timer = osg::Timer::instance();
|
|
||||||
osg::Stats* const stats = mViewer->getViewerStats();
|
|
||||||
while (!mViewer->done() && !mEnvironment.getStateManager()->hasQuitRequest())
|
|
||||||
{
|
|
||||||
while (!luaUpdateRequest)
|
|
||||||
std::this_thread::yield();
|
|
||||||
|
|
||||||
{
|
|
||||||
const osg::Timer_t frameStart = mViewer->getStartTick();
|
|
||||||
const unsigned int frameNumber = mViewer->getFrameStamp()->getFrameNumber();
|
|
||||||
ScopedProfile<UserStatsType::Lua> profile(frameStart, frameNumber, *timer, *stats);
|
|
||||||
|
|
||||||
mLuaManager->update(mEnvironment.getWindowManager()->isGuiMode(), luaDt);
|
|
||||||
}
|
|
||||||
luaUpdateRequest = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Start the main rendering loop
|
// Start the main rendering loop
|
||||||
double simulationTime = 0.0;
|
double simulationTime = 0.0;
|
||||||
|
@ -959,16 +1015,11 @@ void OMW::Engine::go()
|
||||||
|
|
||||||
mEnvironment.getWorld()->updateWindowManager();
|
mEnvironment.getWorld()->updateWindowManager();
|
||||||
|
|
||||||
// scriptingThread starts processing Lua scripts
|
luaWorker.allowUpdate(dt); // if there is a separate Lua thread, it starts the update now
|
||||||
luaDt = dt;
|
|
||||||
luaUpdateRequest = true;
|
|
||||||
|
|
||||||
mViewer->renderingTraversals();
|
mViewer->renderingTraversals();
|
||||||
|
|
||||||
// wait for scriptingThread to finish
|
luaWorker.finishUpdate();
|
||||||
while (luaUpdateRequest)
|
|
||||||
std::this_thread::yield();
|
|
||||||
mLuaManager->applyQueuedChanges();
|
|
||||||
|
|
||||||
bool guiActive = mEnvironment.getWindowManager()->isGuiMode();
|
bool guiActive = mEnvironment.getWindowManager()->isGuiMode();
|
||||||
if (!guiActive)
|
if (!guiActive)
|
||||||
|
@ -991,7 +1042,7 @@ void OMW::Engine::go()
|
||||||
frameRateLimiter.limit();
|
frameRateLimiter.limit();
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptingThread.join();
|
luaWorker.join();
|
||||||
|
|
||||||
// Save user settings
|
// Save user settings
|
||||||
settings.saveUser(settingspath);
|
settings.saveUser(settingspath);
|
||||||
|
|
|
@ -194,6 +194,7 @@ namespace OMW
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Files::ConfigurationManager& mCfgMgr;
|
Files::ConfigurationManager& mCfgMgr;
|
||||||
|
class LuaWorker;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ The ranges included with each setting are the physically possible ranges, not re
|
||||||
HUD
|
HUD
|
||||||
game
|
game
|
||||||
general
|
general
|
||||||
|
lua
|
||||||
shaders
|
shaders
|
||||||
shadows
|
shadows
|
||||||
input
|
input
|
||||||
|
|
17
docs/source/reference/modding/settings/lua.rst
Normal file
17
docs/source/reference/modding/settings/lua.rst
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
Lua Settings
|
||||||
|
############
|
||||||
|
|
||||||
|
lua num threads
|
||||||
|
---------------
|
||||||
|
|
||||||
|
:Type: integer
|
||||||
|
:Range: 0, 1
|
||||||
|
:Default: 1
|
||||||
|
|
||||||
|
The maximum number of threads used for Lua scripts.
|
||||||
|
If zero, Lua scripts are processed in the main thread.
|
||||||
|
If one, a separate thread is used.
|
||||||
|
Values >1 are not yet supported.
|
||||||
|
|
||||||
|
This setting can only be configured by editing the settings configuration file.
|
||||||
|
|
|
@ -1096,3 +1096,10 @@ stomp mode = 2
|
||||||
# 1 - Reduced levels.
|
# 1 - Reduced levels.
|
||||||
# 0 - Gentle levels.
|
# 0 - Gentle levels.
|
||||||
stomp intensity = 1
|
stomp intensity = 1
|
||||||
|
|
||||||
|
[Lua]
|
||||||
|
|
||||||
|
# Set the maximum number of threads used for Lua scripts.
|
||||||
|
# If zero, Lua scripts are processed in the main thread.
|
||||||
|
lua num threads = 1
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue