From 11afa09ea3f56c0e20eb195ae1520a88602ceaca Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 22 Oct 2021 11:36:31 -0400 Subject: SL-16220: Add LL::ThreadPool class and a "General" instance. ThreadPool bundles a WorkQueue with the specified number of worker threads to service it. Each ThreadPool has a name that can be used to locate its WorkQueue. Each worker thread calls WorkQueue::runUntilClose(). ThreadPool listens on the "LLApp" LLEventPump for shutdown notification. On receiving that, it closes its WorkQueue and then join()s each of its worker threads for orderly shutdown. Add a settings.xml entry "ThreadPoolSizes", the first LLSD-valued settings entry to expect a map: pool name->size. The expectation is that usually code instantiating a particular ThreadPool will have a default size in mind, but it should check "ThreadPoolSizes" for a user override. Make idle_startup()'s STATE_SEED_CAP_GRANTED state instantiate a "General" ThreadPool. This is function-static for lazy initialization. Eliminate LLMainLoopRepeater, which is completely unreferenced. Any potential future use cases are better addressed by posting to the main loop's WorkQueue. Eliminate llappviewer.cpp's private LLDeferredTaskList class, which implemented LLAppViewer::addOnIdleCallback(). Make addOnIdleCallback() post work to the main loop's WorkQueue instead. --- indra/llcommon/threadpool.h | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 indra/llcommon/threadpool.h (limited to 'indra/llcommon/threadpool.h') diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h new file mode 100644 index 0000000000..8f3c8514b5 --- /dev/null +++ b/indra/llcommon/threadpool.h @@ -0,0 +1,46 @@ +/** + * @file threadpool.h + * @author Nat Goodspeed + * @date 2021-10-21 + * @brief ThreadPool configures a WorkQueue along with a pool of threads to + * service it. + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Copyright (c) 2021, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_THREADPOOL_H) +#define LL_THREADPOOL_H + +#include "workqueue.h" +#include +#include +#include // std::pair +#include + +namespace LL +{ + + class ThreadPool + { + public: + /** + * Pass ThreadPool a string name. This can be used to look up the + * relevant WorkQueue. + */ + ThreadPool(const std::string& name, size_t threads=1); + ~ThreadPool(); + void close(); + + private: + void run(const std::string& name); + + WorkQueue mQueue; + std::string mName; + std::vector> mThreads; + }; + +} // namespace LL + +#endif /* ! defined(LL_THREADPOOL_H) */ -- cgit v1.2.3 From 834e7ca088b5f417235327cd290b42459c733594 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 4 Nov 2021 17:18:57 -0400 Subject: SL-16202: Use large WorkQueue size limits for mainloop and General. Give ThreadPool and WorkQueue the ability to override default ThreadSafeSchedule capacity. Instantiate "mainloop" WorkQueue and "General" ThreadPool with very large capacity because we never want to have to block trying to push to either. --- indra/llcommon/threadpool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/threadpool.h') diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index 8f3c8514b5..6e3858508b 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -29,7 +29,7 @@ namespace LL * Pass ThreadPool a string name. This can be used to look up the * relevant WorkQueue. */ - ThreadPool(const std::string& name, size_t threads=1); + ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024); ~ThreadPool(); void close(); -- cgit v1.2.3 From ff5496239bffadaca111b1e4380a01447f85843a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 5 Nov 2021 12:33:31 -0400 Subject: SL-16202: Use WorkQueue::postTo() for texture create/post handshake. That is, when LLViewerFetchedTexture::scheduleCreateTexture() wants to call createTexture() on the LLImageGLThread, but postCreateTexture() on the main thread, use the "mainloop" WorkQueue to set up the handshake. Give ThreadPool a public virtual run() method so a subclass can override with desired behavior. This necessitates a virtual destructor. Add accessors for embedded WorkQueue (for post calls), ThreadPool name and width (in threads). Allow LLSimpleton::createInstance() to forward arguments to the subject constructor. Make LLImageGLThread an LLSimpleton - that abstraction didn't yet exist at the time LLImageGLThread was coded. Also derive from ThreadPool rather than LLThread. Make it a single-thread "pool" with a very large queue capacity. --- indra/llcommon/threadpool.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/threadpool.h') diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index 6e3858508b..1ca24aec58 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -30,9 +30,25 @@ namespace LL * relevant WorkQueue. */ ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024); - ~ThreadPool(); + virtual ~ThreadPool(); + + /** + * ThreadPool listens for application shutdown messages on the "LLApp" + * LLEventPump. Call close() to shut down this ThreadPool early. + */ void close(); + std::string getName() const { return mName; } + size_t getWidth() const { return mThreads.size(); } + /// obtain a non-const reference to the WorkQueue to post work to it + WorkQueue& getQueue() { return mQueue; } + + /** + * Override run() if you need special processing. The default run() + * implementation simply calls WorkQueue::runUntilClose(). + */ + virtual void run(); + private: void run(const std::string& name); -- cgit v1.2.3 From 2b96f89c2a374d72c0a8bc28a7b06ad4db7eae6e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 23 Nov 2021 20:39:32 -0500 Subject: SL-16400: Add ThreadPool::start() method, and call it. It's sometimes important to finish other initialization before launching the threads in the ThreadPool, so make that an explicit step. In particular, we were launching the LLImageGL texture thread before initializing the GL context, resulting in all gray textures. --- indra/llcommon/threadpool.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'indra/llcommon/threadpool.h') diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index 1ca24aec58..b79c9b9090 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -32,6 +32,14 @@ namespace LL ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024); virtual ~ThreadPool(); + /** + * Launch the ThreadPool. Until this call, a constructed ThreadPool + * launches no threads. That permits coders to derive from ThreadPool, + * or store it as a member of some other class, but refrain from + * launching it until all other construction is complete. + */ + void start(); + /** * ThreadPool listens for application shutdown messages on the "LLApp" * LLEventPump. Call close() to shut down this ThreadPool early. @@ -54,6 +62,7 @@ namespace LL WorkQueue mQueue; std::string mName; + size_t mThreadCount; std::vector> mThreads; }; -- cgit v1.2.3