Skip to content

Commit 8ce465e

Browse files
DP: implementation of Get Last Feeding time for a buffers
This commit introduces calcualting of LFT for a module following description from zephyr_dp_scheduler.c The implementation is ready for DP to DP deadline calculations, however, the rest of the code is not. Therefore the DP to DP part has been deactivated with proper comment Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
1 parent be9af90 commit 8ce465e

1 file changed

Lines changed: 70 additions & 4 deletions

File tree

src/audio/buffers/audio_buffer.c

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#include <rtos/panic.h>
1111
#include <rtos/alloc.h>
1212
#include <ipc/stream.h>
13+
#include <sof/audio/module_adapter/module/generic.h>
14+
#include <module/ipc4/base-config.h>
15+
#include <sof/audio/component.h>
16+
#include <module/module/base.h>
1317
#include <sof/audio/audio_buffer.h>
1418
#include <sof/audio/sink_api.h>
1519
#include <sof/audio/source_api.h>
@@ -182,12 +186,74 @@ int audio_buffer_source_set_alignment_constants(struct sof_source *source,
182186
return 0;
183187
}
184188

185-
/**
186-
* this is stub, always return Last Feeding Time - 0, meaning "NOW"
187-
*/
188189
uint32_t audio_buffer_buffer_sink_get_lft(struct sof_sink *sink)
189190
{
190-
return 0;
191+
struct sof_audio_buffer *buffer = sof_audio_buffer_from_sink(sink);
192+
/* get number of ms in the buffer */
193+
size_t bytes_per_sec = sink_get_frame_bytes(&buffer->_sink_api) *
194+
sink_get_rate(&buffer->_sink_api);
195+
size_t bytes_per_ms = bytes_per_sec / 1000;
196+
197+
/* round up for frequencies like 44100 */
198+
if (bytes_per_ms * 1000 != bytes_per_sec)
199+
bytes_per_ms++;
200+
uint32_t us_in_buffer =
201+
1000 * source_get_data_available(&buffer->_source_api) / bytes_per_ms;
202+
203+
return us_in_buffer;
204+
205+
/*
206+
* TODO, Currently there's no DP to DP connection
207+
* >>> the code below is never accessible and won't work because of cache incoherence <<<
208+
*
209+
* to make DP to DP connection possible:
210+
*
211+
* 1) module data must be ALWAYS located in non cached memory alias, allowing
212+
* cross core access to params like period (needed below) and calling
213+
* module_get_deadline for the next module, regardless of cores the modules are
214+
* running on
215+
* 2) comp_buffer must be removed from all pipeline code, replaced with a generic abstract
216+
* class audio_buffer - allowing using comp_buffer and ring_buffer without current
217+
* "hybrid buffer" solution
218+
*/
219+
220+
/* a module bound to source API - taking data from source - is data destination */
221+
struct processing_module *data_consumer_mod = source_get_bound_module(&buffer->_source_api);
222+
/* a module bound to sink API - sending data to sink - is data source */
223+
struct processing_module *data_producer_mod = sink_get_bound_module(&buffer->_sink_api);
224+
225+
/* if no module connected to source - no data consumer, LFT is infinite.
226+
* use MAXINT / 2 to avoid any overflows in further calculations.
227+
* Zephyr cannot get deadline for a thread longer than MAXINT CPU cycles, much less
228+
* than the value in microseconds returned here
229+
*/
230+
if (!data_consumer_mod)
231+
return UINT_MAX / 2;
232+
233+
/* in case there's no data producer (should never happen), LFT is NOW */
234+
if (!data_producer_mod)
235+
return 0;
236+
237+
/* if data receiver is LL module, the LFT is NOW + number of ms in buffer */
238+
if (data_consumer_mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL)
239+
return us_in_buffer;
240+
241+
/* destination is DP. calculate correction of deadline if period of data provider module is
242+
* shorter than consumer module
243+
*/
244+
int32_t deadline_correction = 0;
245+
246+
if (data_consumer_mod->dev->period < data_producer_mod->dev->period) {
247+
deadline_correction = (data_consumer_mod->dev->period - us_in_buffer) /
248+
data_producer_mod->dev->period;
249+
if (deadline_correction < 0)
250+
deadline_correction = 0;
251+
else
252+
deadline_correction =
253+
module_get_LPT(data_producer_mod) * deadline_correction;
254+
}
255+
256+
return us_in_buffer + module_get_deadline(data_producer_mod) - deadline_correction;
191257
}
192258

193259
void audio_buffer_init(struct sof_audio_buffer *buffer, uint32_t buffer_type, bool is_shared,

0 commit comments

Comments
 (0)