1c3a7faeb76b5ff9d87e6cb6163899b0aecc030e
[deb_dpdk.git] / app / test-eventdev / evt_main.c
1 /*
2  *   BSD LICENSE
3  *
4  *   Copyright (C) Cavium, Inc 2017.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Cavium, Inc nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <signal.h>
36
37 #include <rte_atomic.h>
38 #include <rte_debug.h>
39 #include <rte_eal.h>
40 #include <rte_eventdev.h>
41
42 #include "evt_options.h"
43 #include "evt_test.h"
44
45 struct evt_options opt;
46 struct evt_test *test;
47
48 static void
49 signal_handler(int signum)
50 {
51         if (signum == SIGINT || signum == SIGTERM) {
52                 printf("\nSignal %d received, preparing to exit...\n",
53                                 signum);
54                 /* request all lcores to exit from the main loop */
55                 *(int *)test->test_priv = true;
56                 rte_wmb();
57
58                 rte_eal_mp_wait_lcore();
59
60                 if (test->ops.eventdev_destroy)
61                         test->ops.eventdev_destroy(test, &opt);
62
63                 if (test->ops.ethdev_destroy)
64                         test->ops.ethdev_destroy(test, &opt);
65
66                 if (test->ops.mempool_destroy)
67                         test->ops.mempool_destroy(test, &opt);
68
69                 if (test->ops.test_destroy)
70                         test->ops.test_destroy(test, &opt);
71
72                 /* exit with the expected status */
73                 signal(signum, SIG_DFL);
74                 kill(getpid(), signum);
75         }
76 }
77
78 static inline void
79 evt_options_dump_all(struct evt_test *test, struct evt_options *opts)
80 {
81         evt_options_dump(opts);
82         if (test->ops.opt_dump)
83                 test->ops.opt_dump(opts);
84 }
85
86 int
87 main(int argc, char **argv)
88 {
89         uint8_t evdevs;
90         int ret;
91
92         signal(SIGINT, signal_handler);
93         signal(SIGTERM, signal_handler);
94
95         ret = rte_eal_init(argc, argv);
96         if (ret < 0)
97                 rte_panic("invalid EAL arguments\n");
98         argc -= ret;
99         argv += ret;
100
101         evdevs = rte_event_dev_count();
102         if (!evdevs)
103                 rte_panic("no eventdev devices found\n");
104
105         /* Populate the default values of the options */
106         evt_options_default(&opt);
107
108         /* Parse the command line arguments */
109         ret = evt_options_parse(&opt, argc, argv);
110         if (ret) {
111                 evt_err("parsing on or more user options failed");
112                 goto error;
113         }
114
115         /* Get struct evt_test *test from name */
116         test = evt_test_get(opt.test_name);
117         if (test == NULL) {
118                 evt_err("failed to find requested test: %s", opt.test_name);
119                 goto error;
120         }
121
122         if (test->ops.test_result == NULL) {
123                 evt_err("%s: ops.test_result not found", opt.test_name);
124                 goto error;
125         }
126
127         /* Verify the command line options */
128         if (opt.dev_id >= rte_event_dev_count()) {
129                 evt_err("invalid event device %d", opt.dev_id);
130                 goto error;
131         }
132         if (test->ops.opt_check) {
133                 if (test->ops.opt_check(&opt)) {
134                         evt_err("invalid command line argument");
135                         evt_options_dump_all(test, &opt);
136                         goto error;
137                 }
138         }
139
140         /* Check the eventdev capability before proceeding */
141         if (test->ops.cap_check) {
142                 if (test->ops.cap_check(&opt) == false) {
143                         evt_info("unsupported test: %s", opt.test_name);
144                         evt_options_dump_all(test, &opt);
145                         ret = EVT_TEST_UNSUPPORTED;
146                         goto nocap;
147                 }
148         }
149
150         /* Dump the options */
151         if (opt.verbose_level)
152                 evt_options_dump_all(test, &opt);
153
154         /* Test specific setup */
155         if (test->ops.test_setup) {
156                 if (test->ops.test_setup(test, &opt))  {
157                         evt_err("failed to setup test: %s", opt.test_name);
158                         goto error;
159
160                 }
161         }
162
163         /* Test specific mempool setup */
164         if (test->ops.mempool_setup) {
165                 if (test->ops.mempool_setup(test, &opt)) {
166                         evt_err("%s: mempool setup failed", opt.test_name);
167                         goto test_destroy;
168                 }
169         }
170
171         /* Test specific ethdev setup */
172         if (test->ops.ethdev_setup) {
173                 if (test->ops.ethdev_setup(test, &opt)) {
174                         evt_err("%s: ethdev setup failed", opt.test_name);
175                         goto mempool_destroy;
176                 }
177         }
178
179         /* Test specific eventdev setup */
180         if (test->ops.eventdev_setup) {
181                 if (test->ops.eventdev_setup(test, &opt)) {
182                         evt_err("%s: eventdev setup failed", opt.test_name);
183                         goto ethdev_destroy;
184                 }
185         }
186
187         /* Launch lcores */
188         if (test->ops.launch_lcores) {
189                 if (test->ops.launch_lcores(test, &opt)) {
190                         evt_err("%s: failed to launch lcores", opt.test_name);
191                         goto eventdev_destroy;
192                 }
193         }
194
195         rte_eal_mp_wait_lcore();
196
197         /* Print the test result */
198         ret = test->ops.test_result(test, &opt);
199 nocap:
200         if (ret == EVT_TEST_SUCCESS) {
201                 printf("Result: "CLGRN"%s"CLNRM"\n", "Success");
202         } else if (ret == EVT_TEST_FAILED) {
203                 printf("Result: "CLRED"%s"CLNRM"\n", "Failed");
204                 return EXIT_FAILURE;
205         } else if (ret == EVT_TEST_UNSUPPORTED) {
206                 printf("Result: "CLYEL"%s"CLNRM"\n", "Unsupported");
207         }
208
209         return 0;
210 eventdev_destroy:
211         if (test->ops.eventdev_destroy)
212                 test->ops.eventdev_destroy(test, &opt);
213
214 ethdev_destroy:
215         if (test->ops.ethdev_destroy)
216                 test->ops.ethdev_destroy(test, &opt);
217
218 mempool_destroy:
219         if (test->ops.mempool_destroy)
220                 test->ops.mempool_destroy(test, &opt);
221
222 test_destroy:
223         if (test->ops.test_destroy)
224                 test->ops.test_destroy(test, &opt);
225 error:
226         return EXIT_FAILURE;
227 }