-
Notifications
You must be signed in to change notification settings - Fork 308
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
Dp shadow as a part of comp_buffer / audio_stream #9106
Dp shadow as a part of comp_buffer / audio_stream #9106
Conversation
f2a328c
to
cc4c60c
Compare
cc4c60c
to
255500c
Compare
as agreed some time ago, parts of structures that should not be modified or accessed directly ("private") should be marked with _ prefix thesofproject#8100 Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
255500c
to
6e8cf3a
Compare
I generally don't agree with "superfluous parentheses", Code "obviously correct" is always better than "correct". |
6e8cf3a
to
f92b378
Compare
|
||
return audio_stream_get_free_bytes(audio_stream); | ||
} | ||
|
||
static int audio_stream_get_buffer(struct sof_sink *sink, size_t req_size, | ||
void **data_ptr, void **buffer_start, size_t *buffer_size) | ||
{ | ||
struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api); | ||
struct audio_stream *audio_stream = container_of(sink, struct audio_stream, _sink_api); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose you could take this 1 step further in the future by having a static inline accessor API that wraps container_of()
f92b378
to
ed5f31e
Compare
Internal CI failed, checking... |
Connection between LL and DP component is implemented bu using double buffering - between comp_buffer and DP component there's additional "shadow" dp_queue Currently shadow buffers are created in module adapter in "prepare" handler and freed in "reset" handler. It may lead to races when there are bind/unbind operation between a components in separate pipelienes, especially when one of the pipelines is already running The commit makes shadow dp_queue to be a part of comp_buffer. When shadow is created, it replaces source or sink interface of audio_stream allowing the module connected to it using all properties of dp_queue, like lockless cross-core connection. Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
Instead of creating dp_queue in module adapter, use shadow buffering provided by comp_bufer It simplifies the code and makes it more race-resistant Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
Dp queues are no longer kept as a list of objects, remove unused list maintenance code and data Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
ed5f31e
to
6ca344f
Compare
Fixed, there was a crash if a bind module wasn't using a module adapter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just some nit-picking, only if you do end up making another revision. Feel free to ignore otherwise
*/ | ||
data_src = &buffer->stream._source_api; | ||
data_dst = dp_queue_get_sink(buffer->stream.dp_queue_source); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty line
size_t to_copy = MIN(MIN(data_available, free_size), limit); | ||
|
||
err = source_to_sink_copy(data_src, data_dst, true, to_copy); | ||
return err; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return source_to_sink_copy(data_src, data_dst, true, to_copy);
and remove err
return &audio_stream->_source_api; | ||
} | ||
struct sof_source * | ||
audio_stream_get_source(struct audio_stream *audio_stream); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one line should do, same below
@@ -159,6 +159,8 @@ struct dp_queue *dp_queue_create(size_t min_available, size_t min_free_space, ui | |||
static inline | |||
void dp_queue_free(struct dp_queue *dp_queue) | |||
{ | |||
if (!dp_queue) | |||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in principle it's probably good, since this makes the function compatible with free()
, rfree()
, etc., but just wondering - can this actually happen? Do we ever have a chance of calling it with NULL
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it can, very often when changes from this PR are applied:
#if CONFIG_ZEPHYR_DP_SCHEDULER
dp_queue_free(buffer->stream.dp_queue_sink);
dp_queue_free(buffer->stream.dp_queue_source);
#endif /* CONFIG_ZEPHYR_DP_SCHEDULER */
there's no condition if freed pointers are not null, and those will be nulls every time the buffer is not shadowed (so - in most cases). More - there may be only one shadow, so one of those will always be null
first time in the history there are 100% checks passed, so better don't update ;) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @marcinszkudlinski for the follow-up. This is clean solution.
This is a follow up to #9063 and a bugfix
The PR is connecting shadow dp_queue tightly with comp_buffer/audio_stream.