-
Notifications
You must be signed in to change notification settings - Fork 350
Tools: Testbench: Track and print heap usage for modules #10593
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
base: main
Are you sure you want to change the base?
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 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -240,7 +240,47 @@ static int parse_input_args(int argc, char **argv, struct testbench_prm *tp) | |||||||||
| return ret; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t) | ||||||||||
| #if CONFIG_IPC_MAJOR_4 | ||||||||||
| static int tb_collect_heap_usage(struct testbench_prm *tp, struct tb_heap_usage_record *records, | ||||||||||
| int *count_out) | ||||||||||
| { | ||||||||||
| struct list_item *item; | ||||||||||
| int count = 0; | ||||||||||
|
|
||||||||||
| list_for_item(item, &tp->widget_list) { | ||||||||||
| struct tplg_comp_info *info = container_of(item, struct tplg_comp_info, item); | ||||||||||
| uint32_t comp_id = IPC4_COMP_ID(info->module_id, info->instance_id); | ||||||||||
| struct comp_dev *dev = ipc4_get_comp_dev(comp_id); | ||||||||||
|
|
||||||||||
| if (!dev || !dev->mod) | ||||||||||
| continue; | ||||||||||
|
|
||||||||||
| /* In testbench environment, skip AIF/DAI because they are not real components. */ | ||||||||||
| if (info->type == SND_SOC_TPLG_DAPM_AIF_IN || | ||||||||||
| info->type == SND_SOC_TPLG_DAPM_AIF_OUT || | ||||||||||
| info->type == SND_SOC_TPLG_DAPM_DAI_IN || | ||||||||||
| info->type == SND_SOC_TPLG_DAPM_DAI_OUT) | ||||||||||
| continue; | ||||||||||
|
|
||||||||||
| if (count >= TB_NUM_WIDGETS_SUPPORTED) { | ||||||||||
| fprintf(stderr, "Error: Too many components for heap records, max %d.\n", | ||||||||||
| TB_NUM_WIDGETS_SUPPORTED); | ||||||||||
| break; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| records[count].module_name = info->name; | ||||||||||
| records[count].heap_max = dev->mod->priv.resources.heap_high_water_mark; | ||||||||||
|
||||||||||
| records[count].heap_max = dev->mod->priv.resources.heap_high_water_mark; | |
| if (module_adapter_heap_usage(dev->mod, &records[count].heap_max) < 0) | |
| continue; |
Copilot
AI
Mar 4, 2026
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.
test_pipeline_stats() no longer prints a trailing blank line when delta_t == 0 (previously it always printed \n). If delta_t can be 0 for short runs or error cases, consider keeping an unconditional newline to avoid the next output running into the summary block.
| (float)frames_out / tp->fs_out * 1000000 / delta_t); | |
| (float)frames_out / tp->fs_out * 1000000 / delta_t); | |
| else | |
| printf("\n"); |
Copilot
AI
Mar 4, 2026
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 error paths that goto out before tb_gettime(&td0) / tb_gettime(&td1) run, td0/td1 can be uninitialized, but delta_t is still computed from them. This is undefined behavior and can print garbage timing (or worse). Initialize td0/td1 and/or gate the delta_t calculation/printing behind a flag that indicates timing was captured.
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.
tb_collect_heap_usage()caps heap records atTB_NUM_WIDGETS_SUPPORTED(16) and breaks out, which will silently drop heap usage for remaining modules on larger topologies. Consider sizing the record buffer to the actual number of non-AIF/DAI components (e.g., first pass to count, then allocate), or introduce a dedicated "max components" constant that is large enough for real-world IPC4 topologies.