Skip to content

Commit a380d21

Browse files
singalsukv2019i
authored andcommitted
Tools: Testbench: Fixes for xt-xcc build and cycles counting
This patch avoids the build errors. Most of the issues are from different types for formatted printing in gcc vs. xt-xcc. The "__attribute__ ((fallthrough));" is not supported in xt-xcc. The xtensa C library does not have clock_gettime() so it is only left out from build. The cycles count and MCPS is printed instead. The include of dlfcn.h is not needed since the testbench no more has dynamic libraries. Structs within structs need to be initialized to zero in xt-xcc with multiple brackets. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 11592fe commit a380d21

7 files changed

Lines changed: 87 additions & 20 deletions

File tree

tools/testbench/common_test.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include "testbench/trace.h"
3030
#include <tplg_parser/topology.h>
3131

32+
#if defined __XCC__
33+
#include <xtensa/tie/xt_timer.h>
34+
#endif
35+
3236
/* testbench helper functions for pipeline setup and trigger */
3337

3438
int tb_setup(struct sof *sof, struct testbench_prm *tp)
@@ -281,3 +285,22 @@ void tb_enable_trace(bool enable)
281285
else
282286
debug_print("trace print disabled\n");
283287
}
288+
289+
void tb_gettime(struct timespec *td)
290+
{
291+
#if !defined __XCC__
292+
clock_gettime(CLOCK_MONOTONIC, td);
293+
#else
294+
td->tv_nsec = 0;
295+
td->tv_sec = 0;
296+
#endif
297+
}
298+
299+
void tb_getcycles(uint64_t *cycles)
300+
{
301+
#if defined __XCC__
302+
*cycles = XT_RSR_CCOUNT();
303+
#else
304+
*cycles = 0;
305+
#endif
306+
}

tools/testbench/file.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ static struct comp_dev *file_new(const struct comp_driver *drv,
617617
cd->fs.write_failed = false;
618618
cd->fs.n = 0;
619619
cd->fs.copy_count = 0;
620+
cd->fs.cycles_count = 0;
620621
dev->state = COMP_STATE_READY;
621622
return dev;
622623

@@ -803,11 +804,13 @@ static int file_copy(struct comp_dev *dev)
803804
struct comp_buffer *buffer;
804805
struct dai_data *dd = comp_get_drvdata(dev);
805806
struct file_comp_data *cd = comp_get_drvdata(dd->dai);
807+
uint64_t cycles0, cycles1;
806808
int snk_frames;
807809
int src_frames;
808810
int bytes = cd->sample_container_bytes;
809811
int ret = 0;
810812

813+
tb_getcycles(&cycles0);
811814
switch (cd->fs.mode) {
812815
case FILE_READ:
813816
/* file component sink buffer */
@@ -859,6 +862,9 @@ static int file_copy(struct comp_dev *dev)
859862
cd->fs.reached_eof);
860863
schedule_task_cancel(dev->pipeline->pipe_task);
861864
}
865+
866+
tb_getcycles(&cycles1);
867+
cd->fs.cycles_count += cycles1 - cycles0;
862868
return ret;
863869
}
864870

tools/testbench/include/testbench/common_test.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct tplg_context;
3636
* into per pipeline data and per topology data structures.
3737
*/
3838
struct testbench_prm {
39+
long long total_cycles;
3940
char *tplg_file; /* topology file to use */
4041
char *input_file[MAX_INPUT_FILE_NUM]; /* input file names */
4142
char *output_file[MAX_OUTPUT_FILE_NUM]; /* output file names */
@@ -104,4 +105,8 @@ int tb_pipeline_reset(struct ipc *ipc, struct pipeline *p);
104105

105106
void debug_print(char *message);
106107

108+
void tb_gettime(struct timespec *td);
109+
110+
void tb_getcycles(uint64_t *cycles);
111+
107112
#endif

tools/testbench/include/testbench/file.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#ifndef _FILE_H
1212
#define _FILE_H
1313

14+
#include <stdint.h>
15+
1416
/**< Convert with right shift a bytes count to samples count */
1517
#define FILE_BYTES_TO_S16_SAMPLES(s) ((s) >> 1)
1618
#define FILE_BYTES_TO_S32_SAMPLES(s) ((s) >> 2)
@@ -29,14 +31,15 @@ enum file_format {
2931

3032
/* file component state */
3133
struct file_state {
32-
char *fn;
34+
uint64_t cycles_count;
3335
FILE *rfh, *wfh; /* read/write file handle */
34-
bool reached_eof;
35-
bool write_failed;
36+
char *fn;
37+
int copy_count;
3638
int n;
3739
enum file_mode mode;
3840
enum file_format f_format;
39-
int copy_count;
41+
bool reached_eof;
42+
bool write_failed;
4043
};
4144

4245
/* file comp data */

tools/testbench/testbench.c

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ static void test_pipeline_get_file_stats(int pipeline_id)
254254
time = cd->pipeline->pipe_task->start;
255255
if (fcd->fs.copy_count == 0)
256256
fcd->fs.copy_count = 1;
257-
printf("file %s: id %d: type %d: samples %d copies %d total time %zu uS avg time %zu uS\n",
257+
printf("file %s: id %d: type %d: samples %d copies %d total time %lu uS avg time %lu uS\n",
258258
fcd->fs.fn, cd->ipc_config.id, cd->drv->type, fcd->fs.n,
259259
fcd->fs.copy_count, time, time / fcd->fs.copy_count);
260260
break;
@@ -356,7 +356,7 @@ static int parse_input_args(int argc, char **argv, struct testbench_prm *tp)
356356
default:
357357
fprintf(stderr, "unknown option %c\n", option);
358358
ret = -EINVAL;
359-
__attribute__ ((fallthrough));
359+
/* fallthrough */
360360
case 'h':
361361
print_usage(argv[0]);
362362
exit(EXIT_SUCCESS);
@@ -487,10 +487,16 @@ static int test_pipeline_start(struct testbench_prm *tp)
487487
static bool test_pipeline_check_state(struct testbench_prm *tp, int state)
488488
{
489489
struct pipeline *p;
490+
uint64_t cycles0, cycles1;
490491
int i;
491492

493+
tb_getcycles(&cycles0);
494+
492495
schedule_ll_run_tasks();
493496

497+
tb_getcycles(&cycles1);
498+
tp->total_cycles += cycles1 - cycles0;
499+
494500
/* Run pipeline until EOF from fileread */
495501
for (i = 0; i < tp->pipeline_num; i++) {
496502
p = get_pipeline_by_id(tp->pipelines[i]);
@@ -522,15 +528,17 @@ static int test_pipeline_load(struct testbench_prm *tp, struct tplg_context *ctx
522528
}
523529

524530
static void test_pipeline_stats(struct testbench_prm *tp,
525-
struct tplg_context *ctx, uint64_t delta)
531+
struct tplg_context *ctx, long long delta_t)
526532
{
527533
int count = 1;
528534
struct ipc_comp_dev *icd;
529535
struct comp_dev *cd;
530536
struct dai_data *dd;
531537
struct pipeline *p;
532538
struct file_comp_data *frcd, *fwcd;
533-
int n_in, n_out;
539+
long long file_cycles, pipeline_cycles;
540+
float pipeline_mcps;
541+
int n_in, n_out, frames_out;
534542
int i;
535543

536544
/* Get pointer to filewrite */
@@ -566,6 +574,7 @@ static void test_pipeline_stats(struct testbench_prm *tp,
566574

567575
n_in = frcd->fs.n;
568576
n_out = fwcd->fs.n;
577+
file_cycles = frcd->fs.cycles_count + fwcd->fs.cycles_count;
569578

570579
/* print test summary */
571580
printf("==========================================================\n");
@@ -586,10 +595,25 @@ static void test_pipeline_stats(struct testbench_prm *tp,
586595
printf("Output[%d] written to file: \"%s\"\n",
587596
i, tp->output_file[i]);
588597
}
598+
frames_out = n_out / tp->channels_out;
589599
printf("Input sample (frame) count: %d (%d)\n", n_in, n_in / tp->channels_in);
590-
printf("Output sample (frame) count: %d (%d)\n", n_out, n_out / tp->channels_out);
591-
printf("Total execution time: %zu us, %.2f x realtime\n\n",
592-
delta, (double)((double)n_out / tp->channels_out / tp->fs_out) * 1000000 / delta);
600+
printf("Output sample (frame) count: %d (%d)\n", n_out, frames_out);
601+
if (tp->total_cycles) {
602+
pipeline_cycles = tp->total_cycles - file_cycles;
603+
pipeline_mcps = (float)pipeline_cycles * tp->fs_out / frames_out / 1e6;
604+
printf("Total execution cycles: %lld\n", tp->total_cycles);
605+
printf("File component cycles: %lld\n", file_cycles);
606+
printf("Pipeline cycles: %lld\n", pipeline_cycles);
607+
printf("Pipeline MCPS: %6.2f\n", pipeline_mcps);
608+
if (!tp->quiet)
609+
printf("Warning: Use -q to avoid printing to increase MCPS.\n");
610+
}
611+
612+
if (delta_t)
613+
printf("Total execution time: %lld us, %.2f x realtime\n",
614+
delta_t, (float)frames_out / tp->fs_out * 1000000 / delta_t);
615+
616+
printf("\n");
593617
}
594618

595619
/*
@@ -602,10 +626,10 @@ static int pipline_test(struct testbench_prm *tp)
602626
struct tplg_context ctx;
603627
struct timespec ts;
604628
struct timespec td0, td1;
629+
long long delta_t;
605630
int err;
606631
int nsleep_time;
607632
int nsleep_limit;
608-
uint64_t delta;
609633

610634
/* build, run and teardown pipelines */
611635
while (dp_count < tp->dynamic_pipeline_iterations) {
@@ -637,7 +661,8 @@ static int pipline_test(struct testbench_prm *tp)
637661
dp_count, err);
638662
break;
639663
}
640-
clock_gettime(CLOCK_MONOTONIC, &td0);
664+
665+
tb_gettime(&td0);
641666

642667
/* sleep to let the pipeline work - we exit at timeout OR
643668
* if copy iterations OR max_samples is reached (whatever first)
@@ -652,8 +677,12 @@ static int pipline_test(struct testbench_prm *tp)
652677
tp->pipeline_duration_ms;
653678

654679
while (nsleep_time < nsleep_limit) {
680+
#if defined __XCC__
681+
err = 0;
682+
#else
655683
/* wait for next tick */
656684
err = nanosleep(&ts, &ts);
685+
#endif
657686
if (err == 0) {
658687
nsleep_time += tp->tick_period_us; /* sleep fully completed */
659688
if (test_pipeline_check_state(tp, SOF_TASK_STATE_CANCEL)) {
@@ -670,17 +699,18 @@ static int pipline_test(struct testbench_prm *tp)
670699
}
671700
}
672701

673-
clock_gettime(CLOCK_MONOTONIC, &td1);
702+
tb_gettime(&td1);
703+
674704
err = test_pipeline_stop(tp);
675705
if (err < 0) {
676706
fprintf(stderr, "error: pipeline stop %d failed %d\n",
677707
dp_count, err);
678708
break;
679709
}
680710

681-
delta = (td1.tv_sec - td0.tv_sec) * 1000000;
682-
delta += (td1.tv_nsec - td0.tv_nsec) / 1000;
683-
test_pipeline_stats(tp, &ctx, delta);
711+
delta_t = (td1.tv_sec - td0.tv_sec) * 1000000;
712+
delta_t += (td1.tv_nsec - td0.tv_nsec) / 1000;
713+
test_pipeline_stats(tp, &ctx, delta_t);
684714

685715
err = test_pipeline_reset(tp);
686716
if (err < 0) {
@@ -705,6 +735,7 @@ int main(int argc, char **argv)
705735

706736
/* initialize input and output sample rates, files, etc. */
707737
debug = 0;
738+
tp.total_cycles = 0;
708739
tp.fs_in = 0;
709740
tp.fs_out = 0;
710741
tp.bits_in = 0;

tools/testbench/topology.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
/* Topology loader to set up components and pipeline */
99

10-
#include <dlfcn.h>
1110
#include <errno.h>
1211
#include <math.h>
1312
#include <stdio.h>
@@ -161,7 +160,7 @@ static int tb_register_pga(struct testbench_prm *tp, struct tplg_context *ctx)
161160
static int tb_register_pipeline(struct testbench_prm *tp, struct tplg_context *ctx)
162161
{
163162
struct sof *sof = ctx->sof;
164-
struct sof_ipc_pipe_new pipeline = {0};
163+
struct sof_ipc_pipe_new pipeline = {{0}};
165164
int ret;
166165

167166
ret = tplg_new_pipeline(ctx, &pipeline, sizeof(pipeline), NULL);

tools/tplg_parser/include/tplg_parser/topology.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ struct tplg_context {
8585
({struct snd_soc_tplg_hdr *ptr; \
8686
ptr = (struct snd_soc_tplg_hdr *)(ctx->tplg_base + ctx->tplg_offset); \
8787
if (ptr->size != sizeof(*ptr)) { \
88-
printf("%s %d hdr size mismatch 0x%x:0x%lx at offset %ld\n", \
88+
printf("%s %d hdr size mismatch 0x%x:0x%zx at offset %ld\n", \
8989
__func__, __LINE__, ptr->size, sizeof(*ptr), \
9090
ctx->tplg_offset); assert(0); \
9191
} \

0 commit comments

Comments
 (0)