blob: 29a7c427a56905ea40af131669945f7a217729b6 [file] [log] [blame]
Igor Opaniukab88c952017-02-14 13:22:54 +02001/*
2 * Copyright (c) 2016, Linaro Limited
Etienne Carrieredfad7d22019-03-05 08:45:21 +01003 * SPDX-License-Identifier: BSD-2-Clause
Igor Opaniukab88c952017-02-14 13:22:54 +02004 */
5
6#include <errno.h>
7#include <fcntl.h>
8#include <inttypes.h>
9#include <limits.h>
10#include <libgen.h>
11#include <pthread.h>
12#include <string.h>
13#include <stdio.h>
14#include <stdbool.h>
15#include <stdlib.h>
16#include <sys/types.h>
17#include <sys/mman.h>
18#include <sys/stat.h>
19#include <sys/wait.h>
20#include <unistd.h>
Igor Opaniukf1f3fd02017-09-14 15:34:56 +030021#include <yaml.h>
Igor Opaniukab88c952017-02-14 13:22:54 +020022
23#include "benchmark_aux.h"
Igor Opaniukf1f3fd02017-09-14 15:34:56 +030024#include "common.h"
Igor Opaniukab88c952017-02-14 13:22:54 +020025
Igor Opaniukf1f3fd02017-09-14 15:34:56 +030026#define MAX_SCALAR 20
27static struct tee_ts_global *bench_ts_global;
Igor Opaniukab88c952017-02-14 13:22:54 +020028
29static const TEEC_UUID pta_benchmark_uuid = PTA_BENCHMARK_UUID;
Igor Opaniukab88c952017-02-14 13:22:54 +020030static TEEC_Context ctx;
31static TEEC_Session sess;
32
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020033static sig_atomic_t is_running;
Igor Opaniukf1f3fd02017-09-14 15:34:56 +030034static yaml_emitter_t emitter;
35
Igor Opaniuk3d566ae2018-01-29 02:41:33 +020036struct consumer_param {
37 pid_t child_pid;
38 char *ts_filepath;
39};
Igor Opaniukf1f3fd02017-09-14 15:34:56 +030040void sigint_handler(int data)
41{
42 (void)data;
43
44 is_running = 0;
45}
46
Igor Opaniukab88c952017-02-14 13:22:54 +020047static void open_bench_pta(void)
48{
49 TEEC_Result res;
50 uint32_t err_origin;
51
52 res = TEEC_InitializeContext(NULL, &ctx);
53 tee_check_res(res, "TEEC_InitializeContext");
54
55 res = TEEC_OpenSession(&ctx, &sess, &pta_benchmark_uuid,
56 TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
57 tee_check_res(res, "TEEC_OpenSession");
58}
59
60static void close_bench_pta(void)
61{
62 /* release benchmark timestamp shm */
Igor Opaniukab88c952017-02-14 13:22:54 +020063 TEEC_CloseSession(&sess);
64 TEEC_FinalizeContext(&ctx);
65}
66
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020067static void alloc_bench_buf(uint32_t cores)
Igor Opaniukab88c952017-02-14 13:22:54 +020068{
69 TEEC_Result res;
70 TEEC_Operation op = { 0 };
71 uint32_t ret_orig;
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020072 intptr_t paddr_ts_buf = 0;
73 size_t size;
Igor Opaniukab88c952017-02-14 13:22:54 +020074
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020075 op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT,
76 TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE);
Igor Opaniukab88c952017-02-14 13:22:54 +020077
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020078 op.params[1].value.a = cores;
Igor Opaniukab88c952017-02-14 13:22:54 +020079
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020080 res = TEEC_InvokeCommand(&sess, BENCHMARK_CMD_REGISTER_MEMREF,
Igor Opaniukab88c952017-02-14 13:22:54 +020081 &op, &ret_orig);
82 tee_check_res(res, "TEEC_InvokeCommand");
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020083
84 paddr_ts_buf = op.params[0].value.a;
85 size = op.params[0].value.b;
86
ChrisG55ecba70d2018-12-06 11:52:29 +010087 INFO("ts buffer paddr = %" PRIiPTR ", size = %zu\n", paddr_ts_buf, size);
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020088 if (paddr_ts_buf) {
89
90 bench_ts_global = mmap_paddr(paddr_ts_buf, size);
91 if (!bench_ts_global)
92 ERROR_EXIT("Failed to allocate timestamp buffer");
93 } else {
94 ERROR_EXIT("Failed to allocate timestamp buffer");
95 }
Igor Opaniukab88c952017-02-14 13:22:54 +020096}
97
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +020098static void free_bench_buf(void)
Igor Opaniukab88c952017-02-14 13:22:54 +020099{
100 TEEC_Result res;
101 TEEC_Operation op = { 0 };
102 uint32_t ret_orig;
103
Igor Opaniuk845a7832018-06-06 14:06:10 +0300104 DBG("Freeing benchmark buffer.");
Igor Opaniukab88c952017-02-14 13:22:54 +0200105 op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE,
106 TEEC_NONE, TEEC_NONE, TEEC_NONE);
107
108 res = TEEC_InvokeCommand(&sess, BENCHMARK_CMD_UNREGISTER,
109 &op, &ret_orig);
110 tee_check_res(res, "TEEC_InvokeCommand");
111}
112
113static void usage(char *progname)
114{
115 fprintf(stderr, "Call latency benchmark tool for OP-TEE\n\n");
116 fprintf(stderr, "Usage:\n");
117 fprintf(stderr, " %s -h\n", progname);
118 fprintf(stderr, " %s host_app [host_app_args]\n", progname);
119 fprintf(stderr, "Options:\n");
120 fprintf(stderr, " -h Print this help and exit\n");
121 fprintf(stderr, " host_app Path to host app to benchmark\n");
122 fprintf(stderr, " host_app_args Original host app args\n");
123}
124
125static int timestamp_pop(struct tee_ts_cpu_buf *cpu_buf,
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +0200126 struct tee_time_st *ts)
Igor Opaniukab88c952017-02-14 13:22:54 +0200127{
128 uint64_t ts_tail;
129
130 if (!cpu_buf && !ts)
131 return RING_BADPARM;
132
133 if (cpu_buf->tail >= cpu_buf->head)
134 return RING_NODATA;
135
136 ts_tail = cpu_buf->tail++;
137 *ts = cpu_buf->stamps[ts_tail & TEE_BENCH_MAX_MASK];
138
139 return 0;
140}
141
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300142static bool init_emitter(FILE *ts_file)
143{
144 yaml_event_t event;
145
146 if (!yaml_emitter_initialize(&emitter))
147 ERROR_RETURN_FALSE("Can't initialize YAML emitter");
148
149 yaml_emitter_set_canonical(&emitter, 0);
150 yaml_emitter_set_unicode(&emitter, 1);
151 yaml_emitter_set_output_file(&emitter, ts_file);
152
153 /* Stream start */
154 if (!yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING))
155 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200156 "Failed to initialize YAML stream start event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300157 if (!yaml_emitter_emit(&emitter, &event))
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200158 ERROR_GOTO(emitter_delete,
159 "Failed to emit YAML stream start event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300160
161 /* Document start */
162 if (!yaml_document_start_event_initialize(&event,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200163 NULL, NULL, NULL, YAML_IMPLICIT))
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300164 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200165 "Failed to initialize YAML document start event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300166 if (!yaml_emitter_emit(&emitter, &event))
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200167 ERROR_GOTO(emitter_delete,
168 "Failed to emit YAML doc start event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300169
170 /* Mapping start */
171 if (!yaml_mapping_start_event_initialize(&event,
172 NULL, NULL , YAML_IMPLICIT,
173 YAML_ANY_SEQUENCE_STYLE))
174 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200175 "Failed to initialize YAML mapping start event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300176 if (!yaml_emitter_emit(&emitter, &event))
177 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200178 "Failed to emit YAML sequence mapping event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300179 /* Key timestamps */
180 yaml_scalar_event_initialize(&event, NULL, NULL,
181 (yaml_char_t *)"timestamps", -1, 1, 1, YAML_PLAIN_SCALAR_STYLE);
182 if (!yaml_emitter_emit(&emitter, &event))
183 ERROR_RETURN_FALSE("Failed to emit YAML scalar");
184
185 /* Sequence start */
186 if (!yaml_sequence_start_event_initialize(&event,
187 NULL, NULL , YAML_IMPLICIT,
188 YAML_ANY_SEQUENCE_STYLE))
189 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200190 "Failed to initialize YAML sequence start event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300191 if (!yaml_emitter_emit(&emitter, &event))
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200192 ERROR_GOTO(emitter_delete,
193 "Failed to emit YAML sequence start event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300194
195 return true;
196emitter_delete:
197 yaml_emitter_delete(&emitter);
198 return false;
199}
200
201static void deinit_emitter()
202{
203 yaml_event_t event;
204
205 /* Sequence cmd */
206 if (!yaml_sequence_end_event_initialize(&event))
207 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200208 "Failed to initialize YAML sequence end event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300209 if (!yaml_emitter_emit(&emitter, &event))
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200210 ERROR_GOTO(emitter_delete,
211 "Failed to emit YAML sequence end event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300212
213 /* Mapping end */
214 if (!yaml_mapping_end_event_initialize(&event))
215 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200216 "Failed to initialize YAML mapping end event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300217 if (!yaml_emitter_emit(&emitter, &event))
218 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200219 "Failed to emit YAML mapping end event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300220
221 /* Document end */
222 if (!yaml_document_end_event_initialize(&event, 0))
223 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200224 "Failed to initialize YAML document end event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300225 if (!yaml_emitter_emit(&emitter, &event))
226 ERROR_GOTO(emitter_delete, "Failed to emit YAML doc end event");
227
228 /* Stream end */
229 if (!yaml_stream_end_event_initialize(&event))
230 ERROR_GOTO(emitter_delete,
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200231 "Failed to initialise YAML stream end event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300232 if (!yaml_emitter_emit(&emitter, &event))
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200233 ERROR_GOTO(emitter_delete,
234 "Failed to emit YAML stream end event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300235
236emitter_delete:
237 yaml_emitter_delete(&emitter);
238}
239
240static bool fill_map(char *var, char *value)
241{
242 yaml_event_t event;
243
244 yaml_scalar_event_initialize(&event, NULL, NULL,
245 (yaml_char_t *)var, -1, 1, 1, YAML_PLAIN_SCALAR_STYLE);
246 if (!yaml_emitter_emit(&emitter, &event))
247 ERROR_RETURN_FALSE("Failed to emit YAML scalar");
248
249 yaml_scalar_event_initialize(&event, NULL, NULL,
250 (yaml_char_t *)value, -1, 1, 1, YAML_PLAIN_SCALAR_STYLE);
251 if (!yaml_emitter_emit(&emitter, &event))
252 ERROR_RETURN_FALSE("Failed to emit YAML scalar");
253
254 return true;
255}
256
257static bool fill_timestamp(uint32_t core, uint64_t count, uint64_t addr,
258 const char *subsystem)
259{
260 yaml_event_t event;
261 char data[MAX_SCALAR];
262
263 /* Mapping start */
264 if (!yaml_mapping_start_event_initialize(&event,
265 NULL, NULL , YAML_IMPLICIT,
266 YAML_ANY_SEQUENCE_STYLE))
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200267 ERROR_RETURN_FALSE(
268 "Failed to initialize YAML mapping start event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300269 if (!yaml_emitter_emit(&emitter, &event))
270 ERROR_RETURN_FALSE("Failed to emit YAML mapping start event");
271
272 snprintf(data, MAX_SCALAR, "%" PRIu32, core);
273 fill_map("core", data);
274
275 snprintf(data, MAX_SCALAR, "%" PRIu64, count);
276 fill_map("counter", data);
277
278 snprintf(data, MAX_SCALAR, "0x%" PRIx64, addr);
279 fill_map("address", data);
280
281 snprintf(data, MAX_SCALAR, "%s", subsystem);
282 fill_map("component", data);
283
284 /* Mapping end */
285 if (!yaml_mapping_end_event_initialize(&event))
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200286 ERROR_RETURN_FALSE(
287 "Failed to initialize YAML mapping end event");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300288 if (!yaml_emitter_emit(&emitter, &event))
289 ERROR_RETURN_FALSE("Failed to emit YAML mapping end event");
290
291 return true;
292}
293
294/*
295 * Consume all timestamps from per-cpu ringbuffers and put everything into
296 * the yaml file.
297 */
Igor Opaniukab88c952017-02-14 13:22:54 +0200298static void *ts_consumer(void *arg)
299{
Yves Leflochb31789d2017-08-01 14:51:18 +0200300 unsigned int i;
301 int ret;
Igor Opaniukab88c952017-02-14 13:22:54 +0200302 bool ts_received = false;
303 uint32_t cores;
304 struct tee_time_st ts_data;
305 FILE *ts_file;
Igor Opaniuk3d566ae2018-01-29 02:41:33 +0200306 struct consumer_param *prm = (struct consumer_param *)arg;
307 char *tsfile_path = prm->ts_filepath;
308 pid_t child_pid = prm->child_pid;
309 size_t teec_dyn_addr = 0;
Igor Opaniukab88c952017-02-14 13:22:54 +0200310
Igor Opaniukab88c952017-02-14 13:22:54 +0200311 if (!tsfile_path)
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300312 ERROR_GOTO(exit, "Wrong timestamp file path");
Igor Opaniukab88c952017-02-14 13:22:54 +0200313
314 cores = get_cores();
315 if (!cores)
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300316 ERROR_GOTO(exit, "Can't receive amount of avalable cores");
Igor Opaniukab88c952017-02-14 13:22:54 +0200317
318 ts_file = fopen(tsfile_path, "w");
319 if (!ts_file)
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300320 ERROR_GOTO(exit, "Can't open timestamp file");
321
322 if (!init_emitter(ts_file))
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200323 ERROR_GOTO(file_close,
324 "Error occurred in emitter initialization");
Igor Opaniukab88c952017-02-14 13:22:54 +0200325
326 while (is_running) {
327 ts_received = false;
328 for (i = 0; i < cores; i++) {
329 ret = timestamp_pop(&bench_ts_global->cpu_buf[i],
330 &ts_data);
331 if (!ret) {
332 ts_received = true;
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +0200333 DBG("Timestamp: core = %u; tick = %lld; "
334 "pc = 0x%" PRIx64 "; system = %s",
335 i, ts_data.cnt, ts_data.addr,
336 bench_str_src(ts_data.src));
Igor Opaniuk845a7832018-06-06 14:06:10 +0300337 do {
Igor Opaniuk3d566ae2018-01-29 02:41:33 +0200338 teec_dyn_addr = get_library_load_offset
339 (child_pid,
340 LIBTEEC_NAME);
Igor Opaniuk845a7832018-06-06 14:06:10 +0300341
342 } while (!teec_dyn_addr && is_running);
Igor Opaniuk3d566ae2018-01-29 02:41:33 +0200343 if (ts_data.src == TEE_BENCH_CLIENT) {
344 DBG("ts_addr = %llx, teec_addr = %x",
345 ts_data.addr, teec_dyn_addr);
346 ts_data.addr -= teec_dyn_addr;
347 }
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300348 if (!fill_timestamp(i, ts_data.cnt,
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +0200349 ts_data.addr,
350 bench_str_src(ts_data.src)))
351 ERROR_GOTO(deinit_yaml,
352 "Adding timestamp failed");
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300353
Igor Opaniukab88c952017-02-14 13:22:54 +0200354 }
355 }
356
Yves Leflochb31789d2017-08-01 14:51:18 +0200357 if (!ts_received) {
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300358 if (is_running) {
359 DBG("yielding...");
Igor Opaniukab88c952017-02-14 13:22:54 +0200360 sched_yield();
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300361 } else {
362 ERROR_GOTO(deinit_yaml,
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +0200363 "No new data in the per-cpu ringbuffers"
364 );
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300365 }
Yves Leflochb31789d2017-08-01 14:51:18 +0200366 }
Igor Opaniukab88c952017-02-14 13:22:54 +0200367 }
368
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300369deinit_yaml:
370 deinit_emitter();
Igor Opaniukab88c952017-02-14 13:22:54 +0200371file_close:
372 fclose(ts_file);
373exit:
374 return NULL;
375}
376
377int main(int argc, char *argv[])
378{
379 int i;
380 int status;
381 pid_t pid;
382 char testapp_path[PATH_MAX];
383 char **testapp_argv;
384 char *res;
385 char *tsfile_path;
386 uint32_t cores;
387 pthread_t consumer_thread;
Igor Opaniuk3d566ae2018-01-29 02:41:33 +0200388 struct consumer_param prm;
Igor Opaniukab88c952017-02-14 13:22:54 +0200389
390 if (argc == 1) {
391 usage(argv[0]);
392 return 0;
393 }
394
395 /* Parse command line */
396 for (i = 1; i < argc; i++) {
397 if (!strcmp(argv[i], "-h")) {
398 usage(argv[0]);
399 return 0;
400 }
401 }
402
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300403 signal(SIGINT, sigint_handler);
404
405 INFO("1. Opening Benchmark Static TA...");
Igor Opaniukab88c952017-02-14 13:22:54 +0200406 open_bench_pta();
407
408 cores = get_cores();
409 if (!cores)
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300410 ERROR_EXIT("Receiving amount of active cores failed");
Igor Opaniukab88c952017-02-14 13:22:54 +0200411
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300412 INFO("2. Allocating per-core buffers, cores detected = %d",
Igor Opaniukab88c952017-02-14 13:22:54 +0200413 cores);
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +0200414 alloc_bench_buf(cores);
Igor Opaniukab88c952017-02-14 13:22:54 +0200415
416 res = realpath(argv[1], testapp_path);
417 if (!res)
418 tee_errx("Failed to get realpath", EXIT_FAILURE);
419
420 alloc_argv(argc, argv, &testapp_argv);
421
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300422 INFO("3. Starting origin host app %s ...", testapp_path);
Igor Opaniukab88c952017-02-14 13:22:54 +0200423
424 /* fork/exec here */
425 pid = fork();
426
427 if (pid == -1) {
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300428 DBG("fork() failed");
429 ERROR_EXIT("Starting origin host application failed.");
Igor Opaniukab88c952017-02-14 13:22:54 +0200430 } else if (pid > 0) {
431 is_running = 1;
Igor Opaniukab88c952017-02-14 13:22:54 +0200432 tsfile_path = malloc(strlen(testapp_path) +
433 strlen(TSFILE_NAME_SUFFIX) + 1);
434 if (!tsfile_path)
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200435 ERROR_EXIT("Memory allocation failed the file path.");
Igor Opaniukab88c952017-02-14 13:22:54 +0200436
437 tsfile_path[0] = '\0';
438 strcat(tsfile_path, testapp_path);
439 strcat(tsfile_path, TSFILE_NAME_SUFFIX);
440
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300441 INFO("Dumping timestamps to %s ...", tsfile_path);
Igor Opaniukab88c952017-02-14 13:22:54 +0200442 print_line();
443
Igor Opaniuk3d566ae2018-01-29 02:41:33 +0200444 prm.child_pid = pid;
445 prm.ts_filepath = tsfile_path;
446
Igor Opaniukab88c952017-02-14 13:22:54 +0200447 if (pthread_create(&consumer_thread, NULL,
Igor Opaniuk3d566ae2018-01-29 02:41:33 +0200448 ts_consumer, &prm)) {
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300449 DBG( "Error creating ts consumer thread");
450 ERROR_EXIT("Can't start process of reading timestamps");
Igor Opaniukab88c952017-02-14 13:22:54 +0200451 }
452 /* wait for child app exits */
453 waitpid(pid, &status, 0);
Igor Opaniuk845a7832018-06-06 14:06:10 +0300454 DBG("Origin host application finished executing");
455
Igor Opaniukab88c952017-02-14 13:22:54 +0200456 is_running = 0;
457
458 /* wait for our consumer thread terminate */
459 if (pthread_join(consumer_thread, NULL)) {
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300460 DBG("Error joining thread");
Igor Opaniuk66e23bf2018-02-06 19:18:59 +0200461 ERROR_EXIT("Couldn't start consuming timestamps");
Igor Opaniukab88c952017-02-14 13:22:54 +0200462 }
463 }
464 else {
465 execvp(testapp_path, testapp_argv);
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300466 DBG("execve() failed");
467 ERROR_EXIT("Starting origin host application failed");
Igor Opaniukab88c952017-02-14 13:22:54 +0200468 }
469
Igor Opaniukf1f3fd02017-09-14 15:34:56 +0300470 INFO("4. Done benchmark");
Igor Opaniukab88c952017-02-14 13:22:54 +0200471
472 dealloc_argv(argc-1, testapp_argv);
Igor Opaniuk55fcc4a2018-02-06 19:20:22 +0200473 free_bench_buf();
Igor Opaniukab88c952017-02-14 13:22:54 +0200474 close_bench_pta();
475 return 0;
476}