Repository navigation
mux: add missing buffer locks #2545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -387,6 +387,7 @@ static int mux_copy(struct comp_dev *dev) | |
| uint32_t frames = -1; | ||
| uint32_t sources_bytes[MUX_MAX_STREAMS] = { 0 }; | ||
| uint32_t sink_bytes; | ||
| uint32_t flags = 0; | ||
|
|
||
| comp_dbg(dev, "mux_copy()"); | ||
|
|
||
|
|
@@ -399,11 +400,14 @@ static int mux_copy(struct comp_dev *dev) | |
| /* align source streams with their respective configurations */ | ||
| list_for_item(clist, &dev->bsource_list) { | ||
| source = container_of(clist, struct comp_buffer, sink_list); | ||
| buffer_lock(source, &flags); | ||
| if (source->source->state == dev->state) { | ||
| num_sources++; | ||
| i = get_stream_index(cd, source->pipeline_id); | ||
| sources[i] = source; | ||
| sources_stream[i] = &source->stream; | ||
| } else { | ||
| buffer_unlock(source, flags); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -414,18 +418,31 @@ static int mux_copy(struct comp_dev *dev) | |
| sink = list_first_item(&dev->bsink_list, struct comp_buffer, | ||
| source_list); | ||
|
|
||
| buffer_lock(sink, &flags); | ||
|
|
||
| /* check if sink is active */ | ||
| if (sink->sink->state != dev->state) | ||
| if (sink->sink->state != dev->state) { | ||
| for (i = 0; i < MUX_MAX_STREAMS; i++) { | ||
| if (!sources[i]) | ||
| continue; | ||
| buffer_unlock(sources[i], flags); | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where is the corresponding buffer_lock for this? Code looks strange.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dbaluta I think it's the one on line 403 (it's in the same function).
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. thanks.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I'm not seeing this, I can see lock(source) and unlock(sources[i]) which seem unaligned as they are different objects. Some inline comments may help here.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lgirdwood They are the same objects.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tlauda this looks error prone.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dbaluta What do you mean?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if simplification would be better here. i.e. /* align source streams with their respective configurations */
list_for_item(clist, &dev->bsource_list) {
source = container_of(clist, struct comp_buffer, sink_list);
buffer_lock(source, &flags);
if (source->source->state == dev->state) {
num_sources++;
i = get_stream_index(cd, source->pipeline_id);
sources[i] = source;
sources_stream[i] = &source->stream;
} else {
buffer_unlock(source, flags);
}
}Means we only have certain source buffers locked, i.e only the buffers that out configuration is telling us to copy from. Would it make more sense to just lock all sources and then unlock all sources ? Another thing that we should do is to change the buffer locks to reader and writer locking. This way we only lock a buffer for reading or writing (i.e.reader lock updates r_ptr and avail, writer lock updates w_ptr and free). This would allow cross core buffers that would not block a core that the current implementation might.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lgirdwood It's definitely candidate for future improvement. This patch is about aligning with rest of the components. mux_copy function is the only one missing locks currently.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, great for the r/w buffer locking update. |
||
|
|
||
| buffer_unlock(sink, flags); | ||
| return 0; | ||
| } | ||
|
|
||
| for (i = 0; i < MUX_MAX_STREAMS; i++) { | ||
| if (!sources[i]) | ||
| continue; | ||
| frames = MIN(frames, | ||
| audio_stream_avail_frames(sources_stream[i], | ||
| &sink->stream)); | ||
| buffer_unlock(sources[i], flags); | ||
| } | ||
|
|
||
| buffer_unlock(sink, flags); | ||
|
|
||
| for (i = 0; i < MUX_MAX_STREAMS; i++) { | ||
| if (!sources[i]) | ||
| continue; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.