Compare commits

...

1 Commits

Author SHA1 Message Date
Sungun Park
7017bde04d Optimize thread variables in ServiceThread
Wraps thread-related member variables in preprocessor checks to ensure
they are excluded when multithreading is not supported. Previously,
these variables were declared unconditionally, leading to unnecessary
memory usage for platforms that don't support multithreading.
2026-01-20 07:42:15 -08:00
3 changed files with 40 additions and 33 deletions

View File

@@ -51,39 +51,39 @@ namespace filament::backend {
DriverBase::DriverBase(const Platform::DriverConfig& driverConfig) noexcept
: mDriverConfig(driverConfig) {
if constexpr (UTILS_HAS_THREADING) {
// This thread services user callbacks
mServiceThread = std::thread([this]() {
JobSystem::setThreadName("ServiceThread");
do {
auto& serviceThreadCondition = mServiceThreadCondition;
auto& serviceThreadCallbackQueue = mServiceThreadCallbackQueue;
#if UTILS_HAS_THREADING
// This thread services user callbacks
mServiceThread = std::thread([this]() {
JobSystem::setThreadName("ServiceThread");
do {
auto& serviceThreadCondition = mServiceThreadCondition;
auto& serviceThreadCallbackQueue = mServiceThreadCallbackQueue;
// wait for some callbacks to dispatch
std::unique_lock<std::mutex> lock(mServiceThreadLock);
while (serviceThreadCallbackQueue.empty() && !mExitRequested) {
serviceThreadCondition.wait(lock);
}
if (mExitRequested) {
break;
}
// move the callbacks to a temporary vector
auto callbacks(std::move(serviceThreadCallbackQueue));
lock.unlock();
// and make sure to call them without our lock held
for (auto[handler, callback, user]: callbacks) {
handler->post(user, callback);
}
} while (true);
});
}
// wait for some callbacks to dispatch
std::unique_lock<std::mutex> lock(mServiceThreadLock);
while (serviceThreadCallbackQueue.empty() && !mExitRequested) {
serviceThreadCondition.wait(lock);
}
if (mExitRequested) {
break;
}
// move the callbacks to a temporary vector
auto callbacks(std::move(serviceThreadCallbackQueue));
lock.unlock();
// and make sure to call them without our lock held
for (auto[handler, callback, user]: callbacks) {
handler->post(user, callback);
}
} while (true);
});
#endif
}
DriverBase::~DriverBase() noexcept {
assert_invariant(mCallbacks.empty());
if constexpr (UTILS_HAS_THREADING) {
stopServiceThread();
}
#if UTILS_HAS_THREADING
stopServiceThread();
#endif
}
// ------------------------------------------------------------------------------------------------
@@ -107,11 +107,14 @@ void DriverBase::CallbackData::release(CallbackData* data) {
void DriverBase::scheduleCallback(CallbackHandler* handler, void* user, CallbackHandler::Callback callback) {
if (handler && UTILS_HAS_THREADING) {
#if UTILS_HAS_THREADING
if (handler) {
std::lock_guard<std::mutex> const lock(mServiceThreadLock);
mServiceThreadCallbackQueue.emplace_back(handler, callback, user);
mServiceThreadCondition.notify_one();
} else {
} else
#endif
{
std::lock_guard<std::mutex> const lock(mPurgeLock);
mCallbacks.emplace_back(user, callback);
}

View File

@@ -238,9 +238,11 @@ protected:
void debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept override;
void debugCommandEnd(CommandStream* cmds, bool synchronous, const char* methodName) noexcept override;
#if UTILS_HAS_THREADING
// Stops the `ServiceThread`. This method is called during destruction but may be called
// explicitly if earlier shutdown is needed. This method is idempotent.
void stopServiceThread() noexcept;
#endif
private:
const Platform::DriverConfig mDriverConfig;
@@ -248,11 +250,13 @@ private:
std::mutex mPurgeLock;
std::vector<std::pair<void*, CallbackHandler::Callback>> mCallbacks;
#if UTILS_HAS_THREADING
std::thread mServiceThread;
std::mutex mServiceThreadLock;
std::condition_variable mServiceThreadCondition;
std::vector<std::tuple<CallbackHandler*, CallbackHandler::Callback, void*>> mServiceThreadCallbackQueue;
bool mExitRequested = false;
#endif
};

View File

@@ -390,9 +390,9 @@ void OpenGLDriver::terminate() {
if (getJobWorker()) {
getJobWorker()->terminate();
}
if constexpr (UTILS_HAS_THREADING) {
stopServiceThread();
}
#if UTILS_HAS_THREADING
stopServiceThread();
#endif
mContext.terminate();
mPlatform.terminate();