@@ -240,7 +240,48 @@ static int parse_input_args(int argc, char **argv, struct testbench_prm *tp)
240240 return ret ;
241241}
242242
243- static void test_pipeline_stats (struct testbench_prm * tp , long long delta_t )
243+ #if CONFIG_IPC_MAJOR_4
244+ static int tb_collect_heap_usage (struct testbench_prm * tp , struct tb_heap_usage_record * records ,
245+ int * count_out )
246+ {
247+ struct list_item * item ;
248+ int count = 0 ;
249+
250+ list_for_item (item , & tp -> widget_list )
251+ {
252+ struct tplg_comp_info * info = container_of (item , struct tplg_comp_info , item );
253+ uint32_t comp_id = IPC4_COMP_ID (info -> module_id , info -> instance_id );
254+ struct comp_dev * dev = ipc4_get_comp_dev (comp_id );
255+
256+ if (!dev || !dev -> mod )
257+ continue ;
258+
259+ /* In testbench environment, skip AIF/DAI because they are not real components. */
260+ if (info -> type == SND_SOC_TPLG_DAPM_AIF_IN ||
261+ info -> type == SND_SOC_TPLG_DAPM_AIF_OUT ||
262+ info -> type == SND_SOC_TPLG_DAPM_DAI_IN ||
263+ info -> type == SND_SOC_TPLG_DAPM_DAI_OUT )
264+ continue ;
265+
266+ if (count >= TB_NUM_WIDGETS_SUPPORTED ) {
267+ fprintf (stderr , "Error: Too many components for heap records, max %d.\n" ,
268+ TB_NUM_WIDGETS_SUPPORTED );
269+ break ;
270+ }
271+
272+ records [count ].module_name = info -> name ;
273+ records [count ].heap_max = (int )dev -> mod -> priv .resources .heap_high_water_mark ;
274+ count ++ ;
275+ }
276+
277+ * count_out = count ;
278+ return 0 ;
279+ }
280+ #endif
281+
282+ static void test_pipeline_stats (struct testbench_prm * tp , long long delta_t ,
283+ struct tb_heap_usage_record * heap_records ,
284+ int heap_records_count )
244285{
245286 long long file_cycles , pipeline_cycles ;
246287 float pipeline_mcps ;
@@ -295,11 +336,15 @@ static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
295336 printf ("Warning: Use -d 3 or smaller value to avoid traces to increase MCPS.\n" );
296337 }
297338
298- if (delta_t )
299- printf ("Total execution time: %lld us, %.2f x realtime\n" ,
300- delta_t , (float )frames_out / tp -> fs_out * 1000000 / delta_t );
339+ if (heap_records_count > 0 ) {
340+ for (i = 0 ; i < heap_records_count ; i ++ )
341+ printf ("Heap usage for module %s: %d bytes\n" ,
342+ heap_records [i ].module_name , heap_records [i ].heap_max );
343+ }
301344
302- printf ("\n" );
345+ if (delta_t )
346+ printf ("Total execution time: %lld us, %.2f x realtime\n\n" , delta_t ,
347+ (float )frames_out / tp -> fs_out * 1000000 / delta_t );
303348}
304349
305350/*
@@ -308,14 +353,16 @@ static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
308353 */
309354static int pipline_test (struct testbench_prm * tp )
310355{
311- float samples_to_ns ;
312- int dp_count = 0 ;
313- struct timespec td0 , td1 ;
356+ struct tb_heap_usage_record heap_usage_records [TB_NUM_WIDGETS_SUPPORTED ];
314357 struct file_state * out_stat ;
358+ struct timespec td0 , td1 ;
315359 long long delta_t ;
316360 int64_t next_control_ns ;
317361 int64_t time_ns ;
362+ float samples_to_ns ;
318363 int err ;
364+ int heap_usage_records_count = 0 ;
365+ int dp_count = 0 ;
319366
320367 /* build, run and teardown pipelines */
321368 while (dp_count < tp -> dynamic_pipeline_iterations ) {
@@ -396,6 +443,9 @@ static int pipline_test(struct testbench_prm *tp)
396443 tb_gettime (& td1 );
397444
398445out :
446+ #if CONFIG_IPC_MAJOR_4
447+ tb_collect_heap_usage (tp , heap_usage_records , & heap_usage_records_count );
448+ #endif
399449 err = tb_set_reset_state (tp );
400450 if (err < 0 ) {
401451 fprintf (stderr , "error: pipeline reset %d failed %d\n" ,
@@ -408,7 +458,7 @@ static int pipline_test(struct testbench_prm *tp)
408458 */
409459 delta_t = (td1 .tv_sec - td0 .tv_sec ) * 1000000 ;
410460 delta_t += (td1 .tv_nsec - td0 .tv_nsec ) / 1000 ;
411- test_pipeline_stats (tp , delta_t );
461+ test_pipeline_stats (tp , delta_t , heap_usage_records , heap_usage_records_count );
412462
413463 err = tb_free_all_pipelines (tp );
414464 if (err < 0 ) {
0 commit comments