diff mbox

[PATCHv2,2/2] example: generator: clean up termination progress

Message ID 1456403706-13309-3-git-send-email-maxim.uvarov@linaro.org
State Accepted
Commit 0fc6f31d7c1e5105b4f0487d435c219ec69ac170
Headers show

Commit Message

Maxim Uvarov Feb. 25, 2016, 12:35 p.m. UTC
Carefully shutdown all resources before exit.

Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
---
 example/generator/odp_generator.c | 61 ++++++++++++++++++++++++++++++++-------
 1 file changed, 51 insertions(+), 10 deletions(-)
diff mbox

Patch

diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index ab8c7fa..b21fc4a 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -98,6 +98,9 @@  typedef struct {
 /** Global pointer to args */
 static args_t *args;
 
+/** Barrier to sync threads execution */
+static odp_barrier_t barrier;
+
 /* helper funcs */
 static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
 static void print_info(char *progname, appl_args_t *appl_args);
@@ -408,6 +411,9 @@  static void *gen_send_thread(void *arg)
 	}
 
 	printf("  [%02i] created mode: SEND\n", thr);
+
+	odp_barrier_wait(&barrier);
+
 	for (;;) {
 		int err;
 
@@ -425,14 +431,14 @@  static void *gen_send_thread(void *arg)
 
 		if (!odp_packet_is_valid(pkt)) {
 			EXAMPLE_ERR("  [%2i] alloc_single failed\n", thr);
-			return NULL;
+			break;
 		}
 
 		err = odp_queue_enq(outq_def, odp_packet_to_event(pkt));
 		if (err != 0) {
 			EXAMPLE_ERR("  [%02i] send pkt err!\n", thr);
 			odp_packet_free(pkt);
-			return NULL;
+			break;
 		}
 
 		if (args->appl.interval != 0) {
@@ -557,6 +563,7 @@  static void *gen_recv_thread(void *arg)
 	}
 
 	printf("  [%02i] created mode: RECEIVE\n", thr);
+	odp_barrier_wait(&barrier);
 
 	for (;;) {
 		if (args->appl.number != -1 &&
@@ -594,8 +601,7 @@  static void print_global_stats(int num_workers)
 	int verbose_interval = 20;
 	odp_thrmask_t thrd_mask;
 
-	while (odp_thrmask_worker(&thrd_mask) < num_workers)
-		continue;
+	odp_barrier_wait(&barrier);
 
 	wait = odp_time_local_from_ns(verbose_interval * ODP_TIME_SEC_IN_NS);
 	next = odp_time_sum(odp_time_local(), wait);
@@ -654,6 +660,9 @@  int main(int argc, char *argv[])
 	odp_timer_pool_param_t tparams;
 	odp_timer_pool_t tp;
 	odp_pool_t tmop;
+	odp_queue_t tq;
+	odp_event_t ev;
+	odp_pktio_t *pktio;
 
 	/* Init ODP before calling anything else */
 	if (odp_init_global(NULL, NULL)) {
@@ -752,20 +761,24 @@  int main(int argc, char *argv[])
 	params.type	   = ODP_POOL_TIMEOUT;
 
 	tmop = odp_pool_create("timeout_pool", &params);
-
-	if (pool == ODP_POOL_INVALID) {
-		EXAMPLE_ERR("Error: packet pool create failed.\n");
+	if (tmop == ODP_POOL_INVALID) {
+		EXAMPLE_ERR("Error: timeout pool create failed.\n");
 		exit(EXIT_FAILURE);
 	}
+
+	pktio = malloc(sizeof(odp_pktio_t) * args->appl.if_count);
+
 	for (i = 0; i < args->appl.if_count; ++i)
-		create_pktio(args->appl.if_names[i], pool);
+		pktio[i] = create_pktio(args->appl.if_names[i], pool);
 
 	/* Create and init worker threads */
 	memset(thread_tbl, 0, sizeof(thread_tbl));
 
+	/* num workers + print thread */
+	odp_barrier_init(&barrier, num_workers + 1);
+
 	if (args->appl.mode == APPL_MODE_PING) {
 		odp_cpumask_t cpu_mask;
-		odp_queue_t tq;
 		int cpu_first, cpu_next;
 
 		odp_cpumask_zero(&cpu_mask);
@@ -817,7 +830,6 @@  int main(int argc, char *argv[])
 			odp_cpumask_t thd_mask;
 			void *(*thr_run_func) (void *);
 			int if_idx;
-			odp_queue_t tq;
 
 			if_idx = i % args->appl.if_count;
 
@@ -866,8 +878,37 @@  int main(int argc, char *argv[])
 	/* Master thread waits for other threads to exit */
 	odph_linux_pthread_join(thread_tbl, num_workers);
 
+	for (i = 0; i < args->appl.if_count; ++i)
+		odp_pktio_stop(pktio[i]);
+
+	for (i = 0; i < num_workers; ++i) {
+		odp_timer_cancel(args->thread[i].tim, &ev);
+		odp_timer_free(args->thread[i].tim);
+		odp_timeout_free(args->thread[i].tmo_ev);
+	}
+
+	for (i = 0; i < num_workers; ++i) {
+		while (1) {
+			ev = odp_queue_deq(args->thread[i].tq);
+			if (ev == ODP_EVENT_INVALID)
+				break;
+			odp_event_free(ev);
+		}
+		odp_queue_destroy(args->thread[i].tq);
+	}
+
+	for (i = 0; i < args->appl.if_count; ++i)
+		odp_pktio_close(pktio[i]);
+	free(pktio);
 	free(args->appl.if_names);
 	free(args->appl.if_str);
+	if (0 != odp_pool_destroy(pool))
+		fprintf(stderr, "unable to destroy pool \"pool\"\n");
+	odp_timer_pool_destroy(tp);
+	if (0 != odp_pool_destroy(tmop))
+		fprintf(stderr, "unable to destroy pool \"tmop\"\n");
+	odp_term_local();
+	odp_term_global();
 	printf("Exit\n\n");
 
 	return 0;