Closed Bug 1559660 Opened 5 years ago Closed 3 years ago

Divert JS offthread tasks to use XPCOM thread pool when the runtime hook is present

Categories

(Core :: JavaScript Engine, enhancement, P2)

enhancement

Tracking

()

RESOLVED FIXED

People

(Reporter: KrisWright, Assigned: jonco)

References

(Depends on 1 open bug, Blocks 1 open bug)

Details

Attachments

(1 obsolete file)

In conjunction with the runtime hook in Bug 1539270, we can dispatch js offthread tasks using the RunnableTask class type to an XPCOM thread pool. In native spidermonkey, these tasks for the most part queue up to their respective thread queues using their respective StartOffThread* functions [1]. If we check for the runtime hook we can instead divert these jobs to XPCOM.

This change requires a few steps, which will need to be done for each offthread type:

  1. Divert jobs to the XPCOM thread pool
    This part is relatively simple - if a runtime hook exists, call the hook and send the jobs to the task handler rather than queueing them up natively. The challenges will come with how the handler dispatches tasks - in GlobalHelperThreadState, individual queues are used for each task type [2]. The way some of these tasks are dispatched is based on whether they are waiting on GC or whether there are other tasks of the same type running. [3]

  2. Successfully complete jobs sent to XPCOM thread pool
    Bug 1559659 goes into detail about some of the issues facing HelperThreads at this step. While calling the runtime hook and sending the task to the thread pool is straightforward, JS offthread tasks' assumptions that they are running on a native helperthread can cause asserts.
    Ion free tasks don't have an explicit task type that can be used to call RunnableTask::runTask() in the task handler [4]. A wrapper that inherits from RunnableTask and calls FreeIonBuilder() on the builder could solve this problem for XPCOM threads.

  3. Successfully clear the job queue on shutdown
    With Bug 1556861 it's possible for the threadpool manager class and HelperThreadTaskHandler to know what kind of task they are sending to the queue. When shutdown is called on the thread pool, this information needs to be used to shut down the pool successfully rather than simply clearing the queue and allowing unpredictable behavior. Some tasks cause race conditions [5] or otherwise hang on shut down, which the native helper thread pool handles on a case by case basis for its task types.

JS helper threads also support prioritization, which XPCOM threads do not as noted in Bug 1502459. This will need to be addressed down the road once js' offthread tasks are able to run on XPCOM thread pools.

[1] https://searchfox.org/mozilla-central/rev/8c09b0389ff4e6263a3f10b1dbd2b6145d7a2aa7/js/src/vm/HelperThreads.h#503
[2] https://searchfox.org/mozilla-central/rev/8c09b0389ff4e6263a3f10b1dbd2b6145d7a2aa7/js/src/vm/HelperThreads.cpp#2447
[3] https://searchfox.org/mozilla-central/rev/8c09b0389ff4e6263a3f10b1dbd2b6145d7a2aa7/js/src/vm/HelperThreads.h#275
[2] https://searchfox.org/mozilla-central/rev/8c09b0389ff4e6263a3f10b1dbd2b6145d7a2aa7/js/src/vm/HelperThreads.cpp#2133
[3] https://searchfox.org/mozilla-central/rev/8c09b0389ff4e6263a3f10b1dbd2b6145d7a2aa7/js/src/vm/HelperThreads.cpp#172

Priority: -- → P2
Depends on: 1569799
Depends on: 1569802
Depends on: 1569819
Depends on: 1570058
Depends on: 1570103

Hi, Kris
So far we only have the interface called HelperThreadTaskCallback to dispatch the task, right?
Can the interface HelperThreadTaskCallback be called on any thread? or can only be on main thread?

I am wondering how do we know the state of the task?
like is it running, or still waiting to be executed, or is already finished?

Or can we 'cancel' the task from main thread?

Also I'd like to know can we 'join' the thread? I only found PR_JoinThread but it is from nspr
Do we have sometime like mutex? If we do, how do we wait on the mutext, and notify, ... etc?

Flags: needinfo?(kwright)

(In reply to Yoshi Cheng-Hao Huang [:allstars.chh][:allstarschh] from comment #1)

Hi, Kris
So far we only have the interface called HelperThreadTaskCallback to dispatch the task, right?
Can the interface HelperThreadTaskCallback be called on any thread? or can only be on main thread?

Hello!
It should be possible to dispatch to an nsThreadPool from any thread, including one of its own threads. I tried to make the abstraction to XPCOM as simple as possible - invoke the callback to dispatch a task, which dispatches to an nsThreadPool. I'm not completely sure what all JS would need but we can implement any features as needed in the wrapper class that dispatches to the thread pool.

I am wondering how do we know the state of the task?
like is it running, or still waiting to be executed, or is already finished?
Or can we 'cancel' the task from main thread?

Runnables aren't designed to be cancelable by nature, though I think it would be possible to implement the existing MozPromise into a callback for promise-based task dispatch. The rest would probably have to be handled from the JS side.

Also I'd like to know can we 'join' the thread? I only found PR_JoinThread but it is from nspr
Do we have sometime like mutex? If we do, how do we wait on the mutext, and notify, ... etc?

As far as I know there's no way to join threads in an nsThreadPool. Mutexes should work the same way they always do. If a mutex needs to be handled by the xpconnect wrapper class in some way (e.g. for scheduling) I can imagine it would be possible to set a callback into it.

Flags: needinfo?(kwright)

This covers the cases where the task derives from js::RunnableTask.

I think I can make some progress on this. More patches soon, I hope.

Assignee: nobody → bwerth

(In reply to Brad Werth [:bradwerth] from comment #4)
Thanks for looking at this but Yoshi is working on this already.

Great! No problem.

Assignee: bwerth → nobody
Assignee: nobody → allstars.chh

Status of April. 23th
I've done the refactoring work in bug 1706357, and updating the HelperThreadTaskCallback interface in bug 1704923.
With the patches from these two bugs, and export the env var MOZ_JS_DISPATCH_TO_EXTERNAL_THREAD_POOL, we can dispatch JS off-thread tasks to XPCOM(TaskController) now. (The try is also green on linux64)

Jonco mentioned one spinning problem in my patch: https://bugzilla.mozilla.org/show_bug.cgi?id=1706357#c9
So I filed bug 1707254 to track this.

Blocks: 1429953

I'm taking over this work while Yoshi is away.

The plan is still to use XPCOM's TaskController pool, without attempting to integrate the JS engine's system of priorities with XPCOM's at this time.

Assignee: allstars.chh → jcoppeard
Depends on: 1713082
Depends on: 1713287
Depends on: 1713335
No longer depends on: 1569799
No longer depends on: 1569802
No longer depends on: 1569819
No longer depends on: 1570058
No longer depends on: 1570103
Depends on: 1714141
Depends on: 1715562

Bug 1715562 has landed with only a couple of minor regressions (now fixed) so I'm going to mark this as fixed.

Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Attachment #9171295 - Attachment is obsolete: true
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: