Commit Graph

27 Commits (9fdca96f8bd2211a99fe88e57b70cbecefa20b6d)

Author SHA1 Message Date
Andrey Lihatskiy 1b68f71348 #824 Process source files in bulk: replace tabs with spaces, convert CRLF to LF, and trim trailing whitespaces as needed 2024-04-29 07:56:09 +03:00
Nat Goodspeed d75ecde69c SL-19690: Properly qualify exception type. 2023-05-08 12:31:57 -04:00
Nat Goodspeed 026ef1935d SL-19690: Follow up on Rye Mutt's fix for shutdown crashes.
Rather than continuing to propagate try/catch (Closed)
(aka LLThreadSafeQueueInterrupt) constructs through the code base, make
WorkQueueBase::post() return bool indicating success (i.e. ! isClosed()).
This obviates postIfOpen(), which no one was using anyway.

In effect, postIfOpen() is renamed post(), bypassing the exception when
isClosed().

Review existing try/catch blocks of that sort, changing to test for post()
returning false.
2023-05-08 12:07:31 -04:00
Rye Mutt 855cae27cc Fix LLThreadSafeQueueInterrupt in WorkQueueBase::postTo during shutdown by catching and returning false 2023-05-05 17:23:29 -04:00
Nat Goodspeed 424d3ef83c DRTVWR-559: Fix broken workqueue_test.cpp.
Apparently Visual Studio and Xcode disagree on the intended lifespan of a
certain temporary expression. Capturing it in a named variable works.
2022-12-13 20:49:01 -05:00
Nat Goodspeed fc424a0db9 SL-18809: Add WorkSchedule; remove timestamps from WorkQueue.
For work queues that don't need timestamped tasks, eliminate the overhead of a
priority queue ordered by timestamp. Timestamped task support moves to
WorkSchedule. WorkQueue is a simpler queue that just waits for work.

Both WorkQueue and WorkSchedule can be accessed via new WorkQueueBase API. Of
course the WorkQueueBase API doesn't deal with timestamps, but a WorkSchedule
can be accessed directly to post timestamped tasks and then handled normally
(e.g. by ThreadPool) to run them.

Most ThreadPool functionality migrates to new ThreadPoolBase class, with
template subclass ThreadPoolUsing<WorkQueue> or ThreadPoolUsing<WorkSchedule>
depending on need. ThreadPool is now an alias for ThreadPoolUsing<WorkQueue>.
Importantly, ThreadPoolUsing::getQueue() delivers a reference to the specific
queue subclass type, so you can post timestamped tasks on a queue retrieved
from ThreadPoolUsing<WorkSchedule>::getQueue().

Since ThreadPool is no longer a simple class but an alias for a particular
template specialization, introduce threadpool_fwd.h to forward-declare it.

Recast workqueue_test.cpp to exercise WorkSchedule, since some of the tests
are time-based. A future todo would be to exercise each applicable test with
both WorkQueue and WorkSchedule.
2022-12-09 13:21:45 -05:00
Andrey Kleshchev 24fb2f8336 Merge branch 'master' (DRTVWR-548) into DRTVWR-559
# Conflicts:
#	indra/llrender/llgl.cpp
#	indra/llrender/llrendertarget.cpp
#	indra/newview/VIEWER_VERSION.txt
#	indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
#	indra/newview/llfloaterpreference.cpp
#	indra/newview/llviewercontrol.cpp
#	indra/newview/llviewermenu.cpp
#	indra/newview/llviewertexturelist.cpp
#	indra/newview/llvovolume.cpp
2022-10-21 18:19:27 +03:00
Cosmic Linden 3e60b53d52 SL-16182: Offload audio decoding from the main thread to the general work queue.
The work queue callback binds "this". This is deemed safe due to current dependencies, but see the associated comment in the return callback. There was some trial and error to get a this-binded lambda to compile.

Due to LLVorbisDecodeState writing to disk off-thread, limit audio decodes proportional to general worker thread count. Guess the thread count for now.
2022-06-14 11:31:52 -07:00
Nat Goodspeed 72ddfbd76e SL-17219: WorkQueue::tryPost() must call ThreadSafeSchedule::tryPush().
We inadvertently changed tryPost() to call ThreadSafeSchedule::tryPost(),
which doesn't exist.
2022-05-10 12:18:27 -04:00
Dave Parks b6841d75c2 SL-17219 WIP - Texture pipeline overhaul 2022-04-15 19:02:07 -05:00
Nat Goodspeed 0b066539fe DRTVWR-546, SL-16220, SL-16094: Undo previous glthread branch revert.
Reverting a merge is sticky: it tells git you never want to see that branch
again. Merging the DRTVWR-546 branch, which contained the revert, into the
glthread branch undid much of the development work on that branch. To restore
it we must revert the revert.

This reverts commit 029b41c041.
2021-11-24 10:47:54 -05:00
Nat Goodspeed d71e0a6d47 SL-16094, SL-16400: Merge branch 'DRTVWR-546' into glthread 2021-11-23 21:23:45 -05:00
Runitai Linden cc34e26ef7 SL-16094 Add WorkQueue profile hooks 2021-11-22 11:51:03 -06:00
Dave Houlton 029b41c041 Revert "SL-16220: Merge branch 'origin/DRTVWR-546' into glthread"
This reverts commit 5188a26a85, reversing
changes made to 819088563e.
2021-11-15 09:25:35 -07:00
Nat Goodspeed df8e17d8e8 SL-16094: Add WorkQueue::size() method to support changeset 08336bb.
We want to skip calling PostMessage() to bump the window thread out of
GetMessage() in any frame with no work functions pending for that thread. That
test depends on being able to sense the size() of the queue. Having converted
to WorkQueue, we need that queue to support size().
2021-11-10 10:13:38 -05:00
Nat Goodspeed 834e7ca088 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.
2021-11-04 17:18:57 -04:00
Nat Goodspeed 89f2169e9d SL-16202: Add postIfOpen() methods to WorkQueue, LLThreadSafeQueue.
postIfOpen() provides a no-exception alternative to post(), which blocks if
full but throws if closed. postIfOpen() likewise blocks if full, but returns
true if able to post and false if the queue was closed.
2021-11-04 16:43:11 -04:00
Nat Goodspeed 7a5b921995 SL-16202: Merge branch 'sl-16220' into glthread 2021-11-04 15:40:30 -04:00
Mnikolenko Productengine 3faba7515c SL-16237 FIXED Viewer hangs on login 2021-11-01 19:38:55 +02:00
Nat Goodspeed 8b16ecb9cf SL-16220: Add tests for WorkQueue::waitForResult(), void & non-void. 2021-10-27 15:31:54 -04:00
Nat Goodspeed f06765cba8 SL-16220: Make WorkQueue::postTo() return exception to caller.
postTo() sets up two-way communication: the caller asks to run work on some
other WorkQueue, expecting an eventual callback on the originating WorkQueue.
That permits us to transport any exception thrown by the work callable back to
rethrow on the originating WorkQueue.
2021-10-26 12:29:49 -04:00
Nat Goodspeed e6eebea8da SL-16220: Change WorkQueue::runOn() to waitForResult().
In addition to the name making the blocking explicit, we changed the
signature: instead of specifying a target WorkQueue on which to run,
waitForResult() runs the passed callable on its own WorkQueue.

Why is that? Because, unlike postTo(), we do not require a handshake between
two different WorkQueues. postTo() allows running arbitrary callback code,
setting variables or whatever, on the originating WorkQueue (presumably on the
originating thread). waitForResult() synchronizes using Promise/Future, which
are explicitly designed for cross-thread communication. We need not call
set_value() on the originating thread, so we don't need a postTo() callback
lambda.
2021-10-26 11:49:53 -04:00
Nat Goodspeed 023d39963e SL-16220: WorkQueue::runOn() methods submit work, wait for result.
The idea is that you can call runOn(target, callable) from a (non-default)
coroutine and block that coroutine until the result becomes available.

As a safety check, we forbid calling runOn() from a thread's default
coroutine, assuming that a given thread's default coroutine is the one
servicing the relevant WorkQueue.
2021-10-25 17:31:27 -04:00
Nat Goodspeed e7b8c27741 SL-16220: Specialize WorkQueue for callable with void return.
Add a test exercising this feature.
2021-10-25 15:55:49 -04:00
Nat Goodspeed 11afa09ea3 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.
2021-10-22 11:36:31 -04:00
Nat Goodspeed 54d874b123 SL-16024: Resolve bizarre VS compile error. Thanks Callum!
It seems CALLBACK is a macro in some Microsoft header file. Bleah.
2021-10-08 11:52:09 -04:00
Nat Goodspeed 623ac79120 SL-16024: Add LL::WorkQueue for passing work items between threads.
A typical WorkQueue has a string name, which can be used to find it to post
work to it. "Work" is a nullary callable.

WorkQueue is a multi-producer, multi-consumer thread-safe queue: multiple
threads can service the WorkQueue, multiple threads can post work to it.

Work can be scheduled in the future by submitting with a timestamp. In
addition, a given work item can be scheduled to run on a recurring basis.

A requesting thread servicing a WorkQueue of its own, such as the viewer's
main thread, can submit work to another WorkQueue along with a callback to be
passed the result (of arbitrary type) of the first work item. The callback is
posted to the originating WorkQueue, permitting safe data exchange between
participating threads.

Methods are provided for different kinds of servicing threads. runUntilClose()
is useful for a simple worker thread. runFor(duration) devotes no more than a
specified time slice to that WorkQueue, e.g. for use by the main thread.
2021-10-07 15:32:51 -04:00