mirror of https://github.com/thesofproject/sof.git
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>
This commit is contained in:
parent
11592fed5b
commit
a380d21d85
|
@ -29,6 +29,10 @@
|
|||
#include "testbench/trace.h"
|
||||
#include <tplg_parser/topology.h>
|
||||
|
||||
#if defined __XCC__
|
||||
#include <xtensa/tie/xt_timer.h>
|
||||
#endif
|
||||
|
||||
/* testbench helper functions for pipeline setup and trigger */
|
||||
|
||||
int tb_setup(struct sof *sof, struct testbench_prm *tp)
|
||||
|
@ -281,3 +285,22 @@ void tb_enable_trace(bool enable)
|
|||
else
|
||||
debug_print("trace print disabled\n");
|
||||
}
|
||||
|
||||
void tb_gettime(struct timespec *td)
|
||||
{
|
||||
#if !defined __XCC__
|
||||
clock_gettime(CLOCK_MONOTONIC, td);
|
||||
#else
|
||||
td->tv_nsec = 0;
|
||||
td->tv_sec = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void tb_getcycles(uint64_t *cycles)
|
||||
{
|
||||
#if defined __XCC__
|
||||
*cycles = XT_RSR_CCOUNT();
|
||||
#else
|
||||
*cycles = 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -617,6 +617,7 @@ static struct comp_dev *file_new(const struct comp_driver *drv,
|
|||
cd->fs.write_failed = false;
|
||||
cd->fs.n = 0;
|
||||
cd->fs.copy_count = 0;
|
||||
cd->fs.cycles_count = 0;
|
||||
dev->state = COMP_STATE_READY;
|
||||
return dev;
|
||||
|
||||
|
@ -803,11 +804,13 @@ static int file_copy(struct comp_dev *dev)
|
|||
struct comp_buffer *buffer;
|
||||
struct dai_data *dd = comp_get_drvdata(dev);
|
||||
struct file_comp_data *cd = comp_get_drvdata(dd->dai);
|
||||
uint64_t cycles0, cycles1;
|
||||
int snk_frames;
|
||||
int src_frames;
|
||||
int bytes = cd->sample_container_bytes;
|
||||
int ret = 0;
|
||||
|
||||
tb_getcycles(&cycles0);
|
||||
switch (cd->fs.mode) {
|
||||
case FILE_READ:
|
||||
/* file component sink buffer */
|
||||
|
@ -859,6 +862,9 @@ static int file_copy(struct comp_dev *dev)
|
|||
cd->fs.reached_eof);
|
||||
schedule_task_cancel(dev->pipeline->pipe_task);
|
||||
}
|
||||
|
||||
tb_getcycles(&cycles1);
|
||||
cd->fs.cycles_count += cycles1 - cycles0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ struct tplg_context;
|
|||
* into per pipeline data and per topology data structures.
|
||||
*/
|
||||
struct testbench_prm {
|
||||
long long total_cycles;
|
||||
char *tplg_file; /* topology file to use */
|
||||
char *input_file[MAX_INPUT_FILE_NUM]; /* input file names */
|
||||
char *output_file[MAX_OUTPUT_FILE_NUM]; /* output file names */
|
||||
|
@ -104,4 +105,8 @@ int tb_pipeline_reset(struct ipc *ipc, struct pipeline *p);
|
|||
|
||||
void debug_print(char *message);
|
||||
|
||||
void tb_gettime(struct timespec *td);
|
||||
|
||||
void tb_getcycles(uint64_t *cycles);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#ifndef _FILE_H
|
||||
#define _FILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**< Convert with right shift a bytes count to samples count */
|
||||
#define FILE_BYTES_TO_S16_SAMPLES(s) ((s) >> 1)
|
||||
#define FILE_BYTES_TO_S32_SAMPLES(s) ((s) >> 2)
|
||||
|
@ -29,14 +31,15 @@ enum file_format {
|
|||
|
||||
/* file component state */
|
||||
struct file_state {
|
||||
char *fn;
|
||||
uint64_t cycles_count;
|
||||
FILE *rfh, *wfh; /* read/write file handle */
|
||||
bool reached_eof;
|
||||
bool write_failed;
|
||||
char *fn;
|
||||
int copy_count;
|
||||
int n;
|
||||
enum file_mode mode;
|
||||
enum file_format f_format;
|
||||
int copy_count;
|
||||
bool reached_eof;
|
||||
bool write_failed;
|
||||
};
|
||||
|
||||
/* file comp data */
|
||||
|
|
|
@ -254,7 +254,7 @@ static void test_pipeline_get_file_stats(int pipeline_id)
|
|||
time = cd->pipeline->pipe_task->start;
|
||||
if (fcd->fs.copy_count == 0)
|
||||
fcd->fs.copy_count = 1;
|
||||
printf("file %s: id %d: type %d: samples %d copies %d total time %zu uS avg time %zu uS\n",
|
||||
printf("file %s: id %d: type %d: samples %d copies %d total time %lu uS avg time %lu uS\n",
|
||||
fcd->fs.fn, cd->ipc_config.id, cd->drv->type, fcd->fs.n,
|
||||
fcd->fs.copy_count, time, time / fcd->fs.copy_count);
|
||||
break;
|
||||
|
@ -356,7 +356,7 @@ static int parse_input_args(int argc, char **argv, struct testbench_prm *tp)
|
|||
default:
|
||||
fprintf(stderr, "unknown option %c\n", option);
|
||||
ret = -EINVAL;
|
||||
__attribute__ ((fallthrough));
|
||||
/* fallthrough */
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
@ -487,10 +487,16 @@ static int test_pipeline_start(struct testbench_prm *tp)
|
|||
static bool test_pipeline_check_state(struct testbench_prm *tp, int state)
|
||||
{
|
||||
struct pipeline *p;
|
||||
uint64_t cycles0, cycles1;
|
||||
int i;
|
||||
|
||||
tb_getcycles(&cycles0);
|
||||
|
||||
schedule_ll_run_tasks();
|
||||
|
||||
tb_getcycles(&cycles1);
|
||||
tp->total_cycles += cycles1 - cycles0;
|
||||
|
||||
/* Run pipeline until EOF from fileread */
|
||||
for (i = 0; i < tp->pipeline_num; i++) {
|
||||
p = get_pipeline_by_id(tp->pipelines[i]);
|
||||
|
@ -522,7 +528,7 @@ static int test_pipeline_load(struct testbench_prm *tp, struct tplg_context *ctx
|
|||
}
|
||||
|
||||
static void test_pipeline_stats(struct testbench_prm *tp,
|
||||
struct tplg_context *ctx, uint64_t delta)
|
||||
struct tplg_context *ctx, long long delta_t)
|
||||
{
|
||||
int count = 1;
|
||||
struct ipc_comp_dev *icd;
|
||||
|
@ -530,7 +536,9 @@ static void test_pipeline_stats(struct testbench_prm *tp,
|
|||
struct dai_data *dd;
|
||||
struct pipeline *p;
|
||||
struct file_comp_data *frcd, *fwcd;
|
||||
int n_in, n_out;
|
||||
long long file_cycles, pipeline_cycles;
|
||||
float pipeline_mcps;
|
||||
int n_in, n_out, frames_out;
|
||||
int i;
|
||||
|
||||
/* Get pointer to filewrite */
|
||||
|
@ -566,6 +574,7 @@ static void test_pipeline_stats(struct testbench_prm *tp,
|
|||
|
||||
n_in = frcd->fs.n;
|
||||
n_out = fwcd->fs.n;
|
||||
file_cycles = frcd->fs.cycles_count + fwcd->fs.cycles_count;
|
||||
|
||||
/* print test summary */
|
||||
printf("==========================================================\n");
|
||||
|
@ -586,10 +595,25 @@ static void test_pipeline_stats(struct testbench_prm *tp,
|
|||
printf("Output[%d] written to file: \"%s\"\n",
|
||||
i, tp->output_file[i]);
|
||||
}
|
||||
frames_out = n_out / tp->channels_out;
|
||||
printf("Input sample (frame) count: %d (%d)\n", n_in, n_in / tp->channels_in);
|
||||
printf("Output sample (frame) count: %d (%d)\n", n_out, n_out / tp->channels_out);
|
||||
printf("Total execution time: %zu us, %.2f x realtime\n\n",
|
||||
delta, (double)((double)n_out / tp->channels_out / tp->fs_out) * 1000000 / delta);
|
||||
printf("Output sample (frame) count: %d (%d)\n", n_out, frames_out);
|
||||
if (tp->total_cycles) {
|
||||
pipeline_cycles = tp->total_cycles - file_cycles;
|
||||
pipeline_mcps = (float)pipeline_cycles * tp->fs_out / frames_out / 1e6;
|
||||
printf("Total execution cycles: %lld\n", tp->total_cycles);
|
||||
printf("File component cycles: %lld\n", file_cycles);
|
||||
printf("Pipeline cycles: %lld\n", pipeline_cycles);
|
||||
printf("Pipeline MCPS: %6.2f\n", pipeline_mcps);
|
||||
if (!tp->quiet)
|
||||
printf("Warning: Use -q to avoid printing to increase MCPS.\n");
|
||||
}
|
||||
|
||||
if (delta_t)
|
||||
printf("Total execution time: %lld us, %.2f x realtime\n",
|
||||
delta_t, (float)frames_out / tp->fs_out * 1000000 / delta_t);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -602,10 +626,10 @@ static int pipline_test(struct testbench_prm *tp)
|
|||
struct tplg_context ctx;
|
||||
struct timespec ts;
|
||||
struct timespec td0, td1;
|
||||
long long delta_t;
|
||||
int err;
|
||||
int nsleep_time;
|
||||
int nsleep_limit;
|
||||
uint64_t delta;
|
||||
|
||||
/* build, run and teardown pipelines */
|
||||
while (dp_count < tp->dynamic_pipeline_iterations) {
|
||||
|
@ -637,7 +661,8 @@ static int pipline_test(struct testbench_prm *tp)
|
|||
dp_count, err);
|
||||
break;
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC, &td0);
|
||||
|
||||
tb_gettime(&td0);
|
||||
|
||||
/* sleep to let the pipeline work - we exit at timeout OR
|
||||
* if copy iterations OR max_samples is reached (whatever first)
|
||||
|
@ -652,8 +677,12 @@ static int pipline_test(struct testbench_prm *tp)
|
|||
tp->pipeline_duration_ms;
|
||||
|
||||
while (nsleep_time < nsleep_limit) {
|
||||
#if defined __XCC__
|
||||
err = 0;
|
||||
#else
|
||||
/* wait for next tick */
|
||||
err = nanosleep(&ts, &ts);
|
||||
#endif
|
||||
if (err == 0) {
|
||||
nsleep_time += tp->tick_period_us; /* sleep fully completed */
|
||||
if (test_pipeline_check_state(tp, SOF_TASK_STATE_CANCEL)) {
|
||||
|
@ -670,7 +699,8 @@ static int pipline_test(struct testbench_prm *tp)
|
|||
}
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &td1);
|
||||
tb_gettime(&td1);
|
||||
|
||||
err = test_pipeline_stop(tp);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "error: pipeline stop %d failed %d\n",
|
||||
|
@ -678,9 +708,9 @@ static int pipline_test(struct testbench_prm *tp)
|
|||
break;
|
||||
}
|
||||
|
||||
delta = (td1.tv_sec - td0.tv_sec) * 1000000;
|
||||
delta += (td1.tv_nsec - td0.tv_nsec) / 1000;
|
||||
test_pipeline_stats(tp, &ctx, delta);
|
||||
delta_t = (td1.tv_sec - td0.tv_sec) * 1000000;
|
||||
delta_t += (td1.tv_nsec - td0.tv_nsec) / 1000;
|
||||
test_pipeline_stats(tp, &ctx, delta_t);
|
||||
|
||||
err = test_pipeline_reset(tp);
|
||||
if (err < 0) {
|
||||
|
@ -705,6 +735,7 @@ int main(int argc, char **argv)
|
|||
|
||||
/* initialize input and output sample rates, files, etc. */
|
||||
debug = 0;
|
||||
tp.total_cycles = 0;
|
||||
tp.fs_in = 0;
|
||||
tp.fs_out = 0;
|
||||
tp.bits_in = 0;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
/* Topology loader to set up components and pipeline */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
@ -161,7 +160,7 @@ static int tb_register_pga(struct testbench_prm *tp, struct tplg_context *ctx)
|
|||
static int tb_register_pipeline(struct testbench_prm *tp, struct tplg_context *ctx)
|
||||
{
|
||||
struct sof *sof = ctx->sof;
|
||||
struct sof_ipc_pipe_new pipeline = {0};
|
||||
struct sof_ipc_pipe_new pipeline = {{0}};
|
||||
int ret;
|
||||
|
||||
ret = tplg_new_pipeline(ctx, &pipeline, sizeof(pipeline), NULL);
|
||||
|
|
|
@ -85,7 +85,7 @@ struct tplg_context {
|
|||
({struct snd_soc_tplg_hdr *ptr; \
|
||||
ptr = (struct snd_soc_tplg_hdr *)(ctx->tplg_base + ctx->tplg_offset); \
|
||||
if (ptr->size != sizeof(*ptr)) { \
|
||||
printf("%s %d hdr size mismatch 0x%x:0x%lx at offset %ld\n", \
|
||||
printf("%s %d hdr size mismatch 0x%x:0x%zx at offset %ld\n", \
|
||||
__func__, __LINE__, ptr->size, sizeof(*ptr), \
|
||||
ctx->tplg_offset); assert(0); \
|
||||
} \
|
||||
|
|
Loading…
Reference in New Issue