Skip to content

wasapi: make render thread exist for the lifetime of the stream object#542

Merged
padenot merged 3 commits into
mozilla:masterfrom
ligfx:wasapi_render_loop_lifecycle
May 17, 2023
Merged

wasapi: make render thread exist for the lifetime of the stream object#542
padenot merged 3 commits into
mozilla:masterfrom
ligfx:wasapi_render_loop_lifecycle

Conversation

@ligfx
Copy link
Copy Markdown
Contributor

@ligfx ligfx commented Sep 14, 2019

Took a crack at this to see what it might look like. See #534 for why I think this could be a good idea.

  • Converts cubeb_stream into a reference-counted object, and gets rid of
    emergency_bailout logic
  • When reconfiguring, only restart a stream if it was already started
  • Removes timeout inside the render thread, as we can't guarantee events
    while a stream is stopped

Copy link
Copy Markdown
Collaborator

@kinetiknz kinetiknz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! The approach generally looks good to me. Do you want me to go ahead and review this as-is?

I suspect we'll need to retain part of the emergency bailout logic. Specifically, we need be sure we never execute callbacks after a stream_stop/stream_destroy.

@ligfx
Copy link
Copy Markdown
Contributor Author

ligfx commented Sep 26, 2019

@kinetiknz

After stream_destroy, the only way I see that a callback would be executed is if WaitForMultipleObjects stalls, and then returns a refill/input_available event even though a shutdown event is also set. Do we know if WaitForMultipleObjects ever stalls, or if the stalls are just inside WASAPI?

After stream_stop is complicated. Even after calling IAudioClient::Stop, the events can still be triggered. I'm seeing usually one more event to fill up the buffer (which executes a callback), and then events with 0 frames left to fill (which doesn't execute a callback, but might unnecessarily add CPU load/thread context switches). How strict is the requirement not to execute callbacks after stream_stop? Thinking through this, I think the only way to accomplish this in every case would be to move the stream start/stop logic inside the render loop thread. Not that complex to code but increases the probability of encountering a stalled thread.

@kinetiknz
Copy link
Copy Markdown
Collaborator

After stream_destroy, the only way I see that a callback would be executed is if WaitForMultipleObjects stalls, and then returns a refill/input_available event even though a shutdown event is also set. Do we know if WaitForMultipleObjects ever stalls, or if the stalls are just inside WASAPI?

Just WASAPI, so this case is fine and I'm just wrong about it. stream_destroy is the important case, since we expect the caller to free resources after the stream is destroyed.

After stream_stop is complicated. Even after calling IAudioClient::Stop, the events can still be triggered. I'm seeing usually one more event to fill up the buffer (which executes a callback), and then events with 0 frames left to fill (which doesn't execute a callback, but might unnecessarily add CPU load/thread context switches). How strict is the requirement not to execute callbacks after stream_stop? Thinking through this, I think the only way to accomplish this in every case would be to move the stream start/stop logic inside the render loop thread. Not that complex to code but increases the probability of encountering a stalled thread.

I think this is fine for now, since it's no different from the behaviour before your changes. Eventually we'll want to tighten this up for all backends, I think.

@ligfx ligfx force-pushed the wasapi_render_loop_lifecycle branch from c71b53a to 9f7318f Compare October 20, 2019 20:29
@ligfx
Copy link
Copy Markdown
Contributor Author

ligfx commented Oct 20, 2019

@kinetiknz Apologies for the delay on this. Rebased to current master (taking extra care around the changes to the thread/bailout logic), and based on the comments above this is ready for review as-is.

@kinetiknz kinetiknz changed the title [PoC] wasapi: make render thread exist for the lifetime of the stream object wasapi: make render thread exist for the lifetime of the stream object Oct 22, 2019
Copy link
Copy Markdown
Collaborator

@kinetiknz kinetiknz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This looks good. I'll merge this soon.

@ligfx
Copy link
Copy Markdown
Contributor Author

ligfx commented Jul 22, 2020

@kinetiknz Are you still interested in this? Happy to rebase and fix conflicts if so.

@danilaml
Copy link
Copy Markdown

@kinetiknz any reason this wasn't merged?

padenot added a commit that referenced this pull request May 2, 2023
@padenot
Copy link
Copy Markdown
Collaborator

padenot commented May 2, 2023

Sorry about that, I think we forgot. I've rebased your initial patch, because the underlying code has changed a lot.

https://github.com/mozilla/cubeb/tree/wasapi_render_loop_lifecycle_rebase is my rebase. I'll change this branch so that it's cleaner, there are various things in a single commit at the moment and CI changes unrelated to your fix.

We now have CI for Windows (as of last week): https://github.com/mozilla/cubeb/actions/runs/4862284679/jobs/8668439986, and I'm trying the patch on Firefox's CI, running most of our media tests, we'll see.

@padenot
Copy link
Copy Markdown
Collaborator

padenot commented May 2, 2023

I'm trying the patch on Firefox's CI, running most of our media tests, we'll see

https://treeherder.mozilla.org/jobs?repo=try&revision=254552db12c035f9a53c5985e4c837b35d4e6cf7. Our CI is having an outage at the moment, but I'm told ops will restart jobs once it's fixed, so we'll have results there.

@padenot
Copy link
Copy Markdown
Collaborator

padenot commented May 4, 2023

@danilaml are you up to review my rebase, since you wrote the code in the first place, and it was already reviewed by @Kinetik (and I had to re-read it for the rebase)? It's at 3e12930. If I haven't screwed up, I'll separate what was your patch orignally from my other fixes, put the right author on the commit and merge.

I've started more tests on Firefox's CI (same link), running the same test suite in opt / non-debug and ASAN enabled, since we're really dealing about lifetimes of resources and such here, can't be too careful. cubeb's CI doesn't run ASAN on Windows yet, and certainly hammers the code less than the full media test suite run of Firefox.

@danilaml
Copy link
Copy Markdown

danilaml commented May 4, 2023

@padenot I think you've made a typo. The original author of this code is @ligfx , not me. I've just discovered it when root causing the bug I was experiencing.

@padenot
Copy link
Copy Markdown
Collaborator

padenot commented May 5, 2023

Ha yes that's what I get for only reading the end of the thread, apologies.

@danilaml
Copy link
Copy Markdown

danilaml commented May 6, 2023

@padenot for the record, I've been running with the rebased branch for a few days so far and haven't encountered any issues (and it did indeed fix the problem I was having). Granted, that's even less coverage than mozilla CI provides, but at least I can confirm that this solves something ;P

@padenot
Copy link
Copy Markdown
Collaborator

padenot commented May 9, 2023

Granted, that's even less coverage than mozilla CI provides

Yes, but the workloads are less synthetic, so it's useful to know, thanks for giving it a try! I'm going to re-read the patch myself and probably merge it.

ligfx and others added 3 commits May 17, 2023 10:43
- Converts cubeb_stream into a reference-counted object, and gets rid of
  emergency_bailout logic
- When reconfiguring, only restart a stream if it was already started
- Removes timeout inside the render thread, as we can't guarantee events
  while a stream is stopped

Subsequently rebased by Paul Adenot <padenot@mozilla.com>
@padenot padenot force-pushed the wasapi_render_loop_lifecycle branch 2 times, most recently from 765c2a0 to d31af33 Compare May 17, 2023 08:51
@padenot
Copy link
Copy Markdown
Collaborator

padenot commented May 17, 2023

@kinetiknz I'm merging this, it's green all around on treeherder and here. I've added a couple commits to be able to have clang-format that has the same results locally and on the CI but it's the same as the original patch (rebased) otherwise.

@padenot padenot merged commit da01c85 into mozilla:master May 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants