summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRunitaiLinden <davep@lindenlab.com>2022-12-07 12:53:59 -0600
committerGitHub <noreply@github.com>2022-12-07 12:53:59 -0600
commite98091e29859ee6a784ee6920048837f2b4536c2 (patch)
treeda1e15d8b8e89a75dfa2ebb3dcb103f6f4b8b276
parent9262c9aeadcf972838c20c5ea917f9c2c60aaddc (diff)
DRTVWR-559: Try using custom fiber scheduler for ThreadPool threads. (#30)
Co-authored-by: Nat Goodspeed <nat@lindenlab.com>
-rw-r--r--indra/llcommon/threadpool.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp
index f49dd40a8b..b0d2016be0 100644
--- a/indra/llcommon/threadpool.cpp
+++ b/indra/llcommon/threadpool.cpp
@@ -23,6 +23,37 @@
#include "llsd.h"
#include "stringize.h"
+#include <boost/fiber/algo/round_robin.hpp>
+
+/*****************************************************************************
+* Custom fiber scheduler for worker threads
+*****************************************************************************/
+// As of 2022-12-06, each of our worker threads only runs a single (default)
+// fiber: we don't launch explicit fibers within worker threads, nor do we
+// anticipate doing so. So a worker thread that's simply waiting for incoming
+// tasks should really sleep a little. Override the default fiber scheduler to
+// implement that.
+struct sleepy_robin: public boost::fibers::algo::round_robin
+{
+ virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept
+ {
+ // round_robin holds a std::condition_variable, and
+ // round_robin::suspend_until() calls
+ // std::condition_variable::wait_until(). On Windows, that call seems
+ // busier than it ought to be. Try just sleeping.
+ Sleep(1);
+ }
+
+ virtual void notify() noexcept
+ {
+ // Since our Sleep() call above will wake up on its own, we need not
+ // take any special action to wake it.
+ }
+};
+
+/*****************************************************************************
+* ThreadPool
+*****************************************************************************/
LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity):
super(name),
mQueue(name, capacity),
@@ -80,6 +111,11 @@ void LL::ThreadPool::close()
void LL::ThreadPool::run(const std::string& name)
{
+#if LL_WINDOWS
+ // Try using sleepy_robin fiber scheduler.
+ boost::fibers::use_scheduling_algorithm<sleepy_robin>();
+#endif // LL_WINDOWS
+
LL_DEBUGS("ThreadPool") << name << " starting" << LL_ENDL;
run();
LL_DEBUGS("ThreadPool") << name << " stopping" << LL_ENDL;