Have Services.profiler.StartProfiler() return a promise that resolves when the child processes are initialized
Categories
(Core :: Gecko Profiler, enhancement, P2)
Tracking
()
People
(Reporter: acreskey, Assigned: mozbugz)
References
(Blocks 1 open bug)
Details
Attachments
(7 files)
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review |
We frequently capture gecko profiles through the browsertime test framework, starting them through the Services.profiler.StartProfiler
api.
Specifically, like so.
However it appears that the content process profiling is not yet initialized because we see cases where the first few seconds of sampling the navigation are missing.
e.g.
https://share.firefox.dev/3nkhWWb
For comparison, if we delay the navigation for a couple of seconds after we start the profiler, we see all the samples on the content process.
e.g.
https://share.firefox.dev/2HUD457
Note that in both cases the content process itself had been created prior to starting the profiler.
So the ask for JS API to allow us to wait until the profiler is initialized and collecting samples on the content process. (Or API to query if the profiler is initialized).
Comment 1•4 years ago
|
||
Do you have an example mach
command to run the browsertime recording you shared?
Comment 2•4 years ago
•
|
||
I think the cause for the delay is the following: When the profiler is started for the first time, each process needs to initialize the stackwalker; on arm64 that's LuL which takes a long time to initialize (bug 1635810). However, we don't parallelize the initialization between the processes. Instead, we first initialize in the parent process, and then we tell the content processes to start profiling, which will then initialize.
The parent process initialization happens synchronously during the StartProfiler call, I think (but I'm not 100% sure). I think we could improve the situation a little bit by telling the other processes to start profiling before we initialize the profiler in the parent process - that way, the LuL initialization will happen in parallel.
Comment 3•4 years ago
|
||
(In reply to Andrew Creskey [:acreskey] [he/him] from comment #0)
So the ask for JS API to allow us to wait until the profiler is initialized and collecting samples on the content process. (Or API to query if the profiler is initialized).
We could also make StartProfiler return a promise which resolves when all processes are done initializing.
Reporter | ||
Comment 4•4 years ago
|
||
Greg, I use browsertime directly from a clone of their repo.
https://github.com/sitespeedio/browsertime
However you can run it from mach
with these steps:
./mach browsertime --setup
and then this should navigate to the given url, capturing a profile:
./mach browsertime https://www.mozilla.org --gecko-profile
Reporter | ||
Comment 5•4 years ago
|
||
(In reply to Markus Stange [:mstange] from comment #3)
(In reply to Andrew Creskey [:acreskey] [he/him] from comment #0)
So the ask for JS API to allow us to wait until the profiler is initialized and collecting samples on the content process. (Or API to query if the profiler is initialized).
We could also make StartProfiler return a promise which resolves when all processes are done initializing.
Oh, yes, as a user I would prefer that.
Comment 6•4 years ago
•
|
||
- LuL initialization
- Child processes are notified
- IPC call
- NotifyProfilerStarted
NotifyProfilerStarted(capacity, duration, interval, features, filters.begin(), // found in profiler_init
NotifyProfilerStarted(aCapacity, aDuration, aInterval, aFeatures, aFilters, // found in profiler_start
NotifyProfilerStarted(aCapacity, aDuration, aInterval, aFeatures, aFilters, // found in profiler_ensure_started
So ultimately, the ordering of operations is:
- profiler_start
- locked_profiler_start
- ActivePS
- SamplerThread
- LUL
- NotifyProfilerStarted
- ProfilerParent::ProfilerStarted
- locked_profiler_start
Comment 7•4 years ago
|
||
I agree that StartProfiler returning a promise would be a good outcome here. I think it would probably be worth initializing LuL in a more parallel fashion, but the original problem would still exist.
Updated•4 years ago
|
Updated•4 years ago
|
Assignee | ||
Comment 8•3 years ago
|
||
I've had a recent need for this (not knowing yet about this bug), and I can see how our Profiler tests could benefit, and others, so I'll have a serious look into it soon.
If possible as well, I'm thinking of adding promises to the other functions that work across processes (stop, pause, resume).
Assignee | ||
Comment 9•3 years ago
|
||
This profiler-controlling functions are used in very few places, so it's good to have them in a separate header to reduce dependencies.
On top of making GeckoProfiler.h lighter, this is actually needed for this bug, because a later patch adds MozPromise to profiler_start and others, which would have created a header loop (GeckoProfiler -> MozPromise -> Monitor -> CondVar -> GeckoProfiler) that makes the build fail.
Assignee | ||
Comment 10•3 years ago
|
||
The returned promise is resolved when the child has completed its operation.
Depends on D139331
Assignee | ||
Comment 11•3 years ago
|
||
Depends on D139332
Assignee | ||
Comment 12•3 years ago
|
||
Depends on D139333
Assignee | ||
Comment 13•3 years ago
|
||
Depends on D139334
Assignee | ||
Comment 14•3 years ago
|
||
In async profiler tests, it's best to await profiler-controlling functions, to ensure that they took full effect in all processes.
It's especially important with StopProfiler, so that the profiler doesn't run anywhere when the following test starts.
Depends on D139335
Assignee | ||
Comment 15•3 years ago
|
||
This can help some tests get the data they expect from child processes.
Depends on D139336
Comment 16•3 years ago
|
||
Comment 17•3 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/92fba281100a
https://hg.mozilla.org/mozilla-central/rev/3ba0ce258e64
https://hg.mozilla.org/mozilla-central/rev/7580f29c6e52
https://hg.mozilla.org/mozilla-central/rev/2008c5a7deb5
https://hg.mozilla.org/mozilla-central/rev/b1ee00c3338d
https://hg.mozilla.org/mozilla-central/rev/ffd92147d48b
https://hg.mozilla.org/mozilla-central/rev/3a326492bafb
Updated•3 years ago
|
Description
•