examples: add eal cleanup to examples
[dpdk.git] / examples / pipeline / main.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9 #include <getopt.h>
10
11 #include <rte_launch.h>
12 #include <rte_eal.h>
13
14 #include "cli.h"
15 #include "conn.h"
16 #include "obj.h"
17 #include "thread.h"
18
19 static const char usage[] =
20         "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n";
21
22 static struct app_params {
23         struct conn_params conn;
24         char *script_name;
25 } app = {
26         .conn = {
27                 .welcome = "\nWelcome!\n\n",
28                 .prompt = "pipeline> ",
29                 .addr = "0.0.0.0",
30                 .port = 8086,
31                 .buf_size = 1024 * 1024,
32                 .msg_in_len_max = 1024,
33                 .msg_out_len_max = 1024 * 1024,
34                 .msg_handle = cli_process,
35                 .msg_handle_arg = NULL, /* set later. */
36         },
37         .script_name = NULL,
38 };
39
40 static int
41 parse_args(int argc, char **argv)
42 {
43         char *app_name = argv[0];
44         struct option lgopts[] = {
45                 { NULL,  0, 0, 0 }
46         };
47         int opt, option_index;
48         int h_present, p_present, s_present, n_args, i;
49
50         /* Skip EAL input args */
51         n_args = argc;
52         for (i = 0; i < n_args; i++)
53                 if (strcmp(argv[i], "--") == 0) {
54                         argc -= i;
55                         argv += i;
56                         break;
57                 }
58
59         if (i == n_args)
60                 return 0;
61
62         /* Parse args */
63         h_present = 0;
64         p_present = 0;
65         s_present = 0;
66
67         while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index))
68                         != EOF)
69                 switch (opt) {
70                 case 'h':
71                         if (h_present) {
72                                 printf("Error: Multiple -h arguments\n");
73                                 return -1;
74                         }
75                         h_present = 1;
76
77                         if (!strlen(optarg)) {
78                                 printf("Error: Argument for -h not provided\n");
79                                 return -1;
80                         }
81
82                         app.conn.addr = strdup(optarg);
83                         if (app.conn.addr == NULL) {
84                                 printf("Error: Not enough memory\n");
85                                 return -1;
86                         }
87                         break;
88
89                 case 'p':
90                         if (p_present) {
91                                 printf("Error: Multiple -p arguments\n");
92                                 return -1;
93                         }
94                         p_present = 1;
95
96                         if (!strlen(optarg)) {
97                                 printf("Error: Argument for -p not provided\n");
98                                 return -1;
99                         }
100
101                         app.conn.port = (uint16_t) atoi(optarg);
102                         break;
103
104                 case 's':
105                         if (s_present) {
106                                 printf("Error: Multiple -s arguments\n");
107                                 return -1;
108                         }
109                         s_present = 1;
110
111                         if (!strlen(optarg)) {
112                                 printf("Error: Argument for -s not provided\n");
113                                 return -1;
114                         }
115
116                         app.script_name = strdup(optarg);
117                         if (app.script_name == NULL) {
118                                 printf("Error: Not enough memory\n");
119                                 return -1;
120                         }
121                         break;
122
123                 default:
124                         printf(usage, app_name);
125                         return -1;
126                 }
127
128         optind = 1; /* reset getopt lib */
129
130         return 0;
131 }
132
133 int
134 main(int argc, char **argv)
135 {
136         struct conn *conn;
137         struct obj *obj;
138         int status;
139
140         /* Parse application arguments */
141         status = parse_args(argc, argv);
142         if (status < 0)
143                 return status;
144
145         /* EAL */
146         status = rte_eal_init(argc, argv);
147         if (status < 0) {
148                 printf("Error: EAL initialization failed (%d)\n", status);
149                 return status;
150         };
151
152         /* Obj */
153         obj = obj_init();
154         if (!obj) {
155                 printf("Error: Obj initialization failed (%d)\n", status);
156                 return status;
157         }
158
159         /* Thread */
160         status = thread_init();
161         if (status) {
162                 printf("Error: Thread initialization failed (%d)\n", status);
163                 return status;
164         }
165
166         rte_eal_mp_remote_launch(
167                 thread_main,
168                 NULL,
169                 SKIP_MAIN);
170
171         /* Script */
172         if (app.script_name)
173                 cli_script_process(app.script_name,
174                         app.conn.msg_in_len_max,
175                         app.conn.msg_out_len_max,
176                         obj);
177
178         /* Connectivity */
179         app.conn.msg_handle_arg = obj;
180         conn = conn_init(&app.conn);
181         if (!conn) {
182                 printf("Error: Connectivity initialization failed (%d)\n",
183                         status);
184                 return status;
185         };
186
187         /* Dispatch loop */
188         for ( ; ; ) {
189                 conn_poll_for_conn(conn);
190
191                 conn_poll_for_msg(conn);
192         }
193
194         /* clean up the EAL */
195         rte_eal_cleanup();
196 }