From eda264c2821a86505b4ec2a898ff3169ab82f895 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 20 Oct 2021 18:38:36 -0400 Subject: SL-16220: Add a WorkQueue to be serviced by mainloop. Make LLAppViewer::idle() call LL::WorkQueue::runFor() to dequeue and run some or all of the pending responses from worker threads. Add a MainWorkTime setting to specify the time slice the main loop may devote each frame to servicing such responses. --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llappviewer.cpp | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'indra/newview') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 05c3fc3bfe..802453d508 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3858,6 +3858,17 @@ Value 1 + MainWorkTime + + Comment + Max time per frame devoted to mainloop work queue (in milliseconds) + Persist + 1 + Type + F32 + Value + 0.1 + QueueInventoryFetchTimeout Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 722a6caa65..7c932a3959 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -233,6 +233,8 @@ #include "llavatariconctrl.h" #include "llgroupiconctrl.h" #include "llviewerassetstats.h" +#include "workqueue.h" +using namespace LL; // Include for security api initialization #include "llsecapi.h" @@ -366,6 +368,8 @@ BOOL gLogoutInProgress = FALSE; BOOL gSimulateMemLeak = FALSE; +WorkQueue gMainloopWork("mainloop"); + //////////////////////////////////////////////////////////// // Internal globals... that should be removed. static std::string gArgs; @@ -5210,6 +5214,20 @@ void LLAppViewer::idle() // Execute deferred tasks. LLDeferredTaskList::instance().run(); + // Service the WorkQueue we use for replies from worker threads. + // Use function statics for the timeslice setting so we only have to fetch + // and convert MainWorkTime once. + static F32 MainWorkTimeRaw = gSavedSettings.getF32("MainWorkTime"); + static F32Milliseconds MainWorkTimeMs(MainWorkTimeRaw); + // MainWorkTime is specified in fractional milliseconds, but std::chrono + // uses integer representations. What if we want less than a microsecond? + // Use nanoseconds. We're very sure we will never need to specify a + // MainWorkTime that would be larger than we could express in + // std::chrono::nanoseconds. + static std::chrono::nanoseconds MainWorkTimeNanoSec{ + std::chrono::nanoseconds::rep(MainWorkTimeMs.value() * 1000000)}; + gMainloopWork.runFor(MainWorkTimeNanoSec); + // Handle shutdown process, for example, // wait for floaters to close, send quit message, // forcibly quit if it has taken too long -- cgit v1.2.3