EM-ODP  3.7.0
Event Machine on ODP
em_cli.c
1 /* Copyright (c) 2021, Nokia
2  * All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "em_include.h"
8 
9 #if EM_CLI
10 
11 #define OPTPARSE_IMPLEMENTATION
12 #include "misc/optparse.h"
13 #include <errno.h>
14 
15 /* Maximum number of bytes (including terminating null byte) for an EM CLI command */
16 #define MAX_CMD_LEN 20
17 
18 /* EM CLI shared memory */
19 static em_cli_shm_t *cli_shm;
20 
21 __attribute__((format(printf, 2, 3)))
22 static int cli_log(em_log_level_t level, const char *fmt, ...)
23 {
24  (void)level;
25 
26  va_list args;
27 
28  va_start(args, fmt);
29 
30  int r = odph_cli_log_va(fmt, args);
31 
32  va_end(args);
33 
34  return r;
35 }
36 
37 static int cli_vlog(em_log_level_t level, const char *fmt, va_list args)
38 {
39  (void)level;
40 
41  return odph_cli_log_va(fmt, args);
42 }
43 
44 static void print_em_info_help(void)
45 {
46  const char *usage = "Usage: em_info_print [OPTION]\n"
47  "Print EM related information.\n"
48  "\n"
49  "Options:\n"
50  " -a, --all\tPrint all EM info\n"
51  " -p, --cpu-arch\tPrint cpu architecture\n"
52  " -c, --conf\tPrint default and runtime configurations\n"
53  " -h, --help\tDisplay this help\n";
54  odph_cli_log(usage);
55 }
56 
57 static void print_em_info_all(void)
58 {
59  core_log_fn_set(cli_log);
60  core_vlog_fn_set(cli_vlog);
61  print_em_info();
62  core_log_fn_set(NULL);
63  core_vlog_fn_set(NULL);
64 }
65 
66 static void print_em_info_cpu_arch(void)
67 {
68  core_log_fn_set(cli_log);
69  core_vlog_fn_set(cli_vlog);
70  print_cpu_arch_info();
71  core_log_fn_set(NULL);
72  core_vlog_fn_set(NULL);
73 }
74 
75 static void print_em_info_conf(void)
76 {
77  core_log_fn_set(cli_log);
78  core_vlog_fn_set(cli_vlog);
79  em_libconfig_print(&em_shm->libconfig);
80  core_log_fn_set(NULL);
81  core_vlog_fn_set(NULL);
82 }
83 
84 static void cmd_em_info_print(int argc, char *argv[])
85 {
86  /* All current options accept no argument */
87  const int max_args = 1;
88 
89  /* When no argument is given, print all EM info */
90  if (argc == 0) {
91  print_em_info_all();
92  return;
93  } else if (argc > max_args) {
94  odph_cli_log("Error: extra parameter given to command!\n");
95  return;
96  }
97 
98  /* Unlike getopt, optparse does not require an argument count as input to
99  * indicate the number of arguments in argv. Instead, it uses NULL pointer
100  * to decide the end of argument array argv.
101  *
102  * argv here contains only CLI command options. To emulate a real command,
103  * argv_new is constructed to include command name.
104  */
105  argc += 1/*Command name*/ + 1/*Terminating NULL pointer*/;
106  char *argv_new[argc];
107  char cmd[MAX_CMD_LEN] = "em_info_print";
108 
109  argv_new[0] = cmd;
110  for (int i = 1; i < argc - 1; i++)
111  argv_new[i] = argv[i - 1];
112  argv_new[argc - 1] = NULL; /*Terminating NULL pointer*/
113 
114  int option;
115  struct optparse_long longopts[] = {
116  {"all", 'a', OPTPARSE_NONE},
117  {"cpu-arch", 'p', OPTPARSE_NONE},
118  {"conf", 'c', OPTPARSE_NONE},
119  {"help", 'h', OPTPARSE_NONE},
120  {0}
121  };
122  struct optparse options;
123 
124  optparse_init(&options, argv_new);
125  options.permute = 0;
126  while (1) {
127  option = optparse_long(&options, longopts, NULL);
128 
129  if (option == -1)
130  break;
131 
132  switch (option) {
133  case 'a':
134  print_em_info_all();
135  break;
136  case 'p':
137  print_em_info_cpu_arch();
138  break;
139  case 'c':
140  print_em_info_conf();
141  break;
142  case 'h':
143  print_em_info_help();
144  break;
145  case '?':
146  odph_cli_log("Error: %s\n", options.errmsg);
147  return;
148  default:
149  odph_cli_log("Unknown Error\n");
150  return;
151  }
152  }
153 }
154 
155 static void print_em_pool_all(void)
156 {
157  core_log_fn_set(cli_log);
158  core_vlog_fn_set(cli_vlog);
160  core_log_fn_set(NULL);
161  core_vlog_fn_set(NULL);
162 }
163 
164 static void print_em_pool(em_pool_t pool, const char *pool_name)
165 {
166  if (pool == EM_POOL_UNDEF) {
167  if (pool_name)
168  odph_cli_log("Error: can't find EM pool %s.\n", pool_name);
169  else
170  odph_cli_log("Error: can't find EM pool %" PRI_POOL "\n", pool);
171  return;
172  }
173 
174  core_log_fn_set(cli_log);
175  core_vlog_fn_set(cli_vlog);
176  pool_info_print_hdr(1);
177  pool_info_print(pool);
178  core_log_fn_set(NULL);
179  core_vlog_fn_set(NULL);
180 }
181 
182 static void print_em_pool_help(void)
183 {
184  const char *usage = "Usage: em_pool_print [OPTION]\n"
185  "Print EM pool related information\n"
186  "\n"
187  "Options:\n"
188  " -a, --all\tPrint info of all pools\n"
189  " -i, --id <pool id>\tPrint info of <pool id>\n"
190  " -n, --name <pool name>\tPrint info of <pool name>\n"
191  " -h, --help\tDisplay this help\n";
192 
193  odph_cli_log(usage);
194 }
195 
196 static void cmd_em_pool_print(int argc, char *argv[])
197 {
198  /* Command em_pool_print takes maximum 2 arguments */
199  const int max_args = 2;
200 
201  /* When no argument is given, print all pool info */
202  if (argc == 0) {
203  print_em_pool_all();
204  return;
205  } else if (argc > max_args) {
206  odph_cli_log("Error: extra parameter given to command!\n");
207  return;
208  }
209 
210  /* Unlike getopt, optparse does not require an argument count as input to
211  * indicate the number of arguments in argv. Instead, it uses NULL pointer
212  * to decide the end of argument array argv.
213  *
214  * argv here contains only CLI command options. To emulate a real command,
215  * argv_new is constructed to include command name.
216  */
217  argc += 1/*Cmd str "em_pool_print"*/ + 1/*Terminating NULL pointer*/;
218  char *argv_new[argc];
219  char cmd[MAX_CMD_LEN] = "em_pool_print";
220 
221  argv_new[0] = cmd;
222  for (int i = 1; i < argc - 1; i++)
223  argv_new[i] = argv[i - 1];
224  argv_new[argc - 1] = NULL; /*Terminating NULL pointer*/
225 
226  em_pool_t pool;
227  int option;
228  struct optparse_long longopts[] = {
229  {"all", 'a', OPTPARSE_NONE},
230  {"id", 'i', OPTPARSE_REQUIRED},
231  {"name", 'n', OPTPARSE_REQUIRED},
232  {"help", 'h', OPTPARSE_NONE},
233  {0}
234  };
235  struct optparse options;
236 
237  optparse_init(&options, argv_new);
238  options.permute = 0;
239  while (1) {
240  option = optparse_long(&options, longopts, NULL);
241  if (option == -1) /* No more options */
242  break;
243 
244  switch (option) {
245  case 'a':
246  print_em_pool_all();
247  break;
248  case 'i':
249  pool = (em_pool_t)(uintptr_t)(int)strtol(options.optarg, NULL, 0);
250  print_em_pool(pool, NULL);
251  break;
252  case 'n':
253  pool = pool_find(options.optarg);
254  print_em_pool(pool, options.optarg);
255  break;
256  case 'h':
257  print_em_pool_help();
258  break;
259  case '?':
260  odph_cli_log("Error: %s\n", options.errmsg);
261  return;
262  default:
263  odph_cli_log("Unknown Error\n");
264  return;
265  }
266  }
267 }
268 
269 static void
270 print_em_pool_stats(em_pool_t pool, const char *pool_name, const em_pool_stats_opt_t *opt)
271 {
272  if (pool == EM_POOL_UNDEF) {
273  if (pool_name)
274  odph_cli_log("Error: can't find EM pool %s.\n", pool_name);
275  else
276  odph_cli_log("Error: can't find EM pool %" PRI_POOL "\n", pool);
277  return;
278  }
279 
280  core_log_fn_set(cli_log);
281  core_vlog_fn_set(cli_vlog);
282 
283  if (opt)
284  pool_stats_selected_print(pool, opt);
285  else
286  pool_stats_print(pool);
287 
288  core_log_fn_set(NULL);
289  core_vlog_fn_set(NULL);
290 }
291 
292 static int str_to_long(const char *str, long *num/*out*/, int base)
293 {
294  char *endptr;
295 
296  errno = 0;
297  *num = strtol(str, &endptr, base);
298  if (errno) {
299  odph_cli_log("strtol failed\n");
300  return -1;
301  }
302 
303  if (endptr == str) {
304  odph_cli_log("No digit is found in given str: %s\n", str);
305  return -1;
306  }
307 
308  if (*endptr != '\0')
309  odph_cli_log("Extra characters not used in str: %s\n", endptr);
310 
311  return 0;
312 }
313 
314 /* Parse string statistic counter options to options in type em_pool_stats_opt_t */
315 static void str_to_opt(const char *str_opt, em_pool_stats_opt_t * const opt)
316 {
317  long stats_opt;
318 
319  /* Parse statistic counter options */
320  if (str_to_long(str_opt, &stats_opt, 16))
321  return;
322 
323  if (stats_opt & 0x80) {
324  odph_cli_log("available is selected\n");
325  opt->available = 1;
326  }
327 
328  if (stats_opt & 0x40) {
329  odph_cli_log("alloc_ops is selected\n");
330  opt->alloc_ops = 1;
331  }
332 
333  if (stats_opt & 0x20) {
334  odph_cli_log("alloc_fails is selected\n");
335  opt->alloc_fails = 1;
336  }
337 
338  if (stats_opt & 0x10) {
339  odph_cli_log("free_ops is selected\n");
340  opt->free_ops = 1;
341  }
342 
343  if (stats_opt & 0x08) {
344  odph_cli_log("total_ops is selected\n");
345  opt->total_ops = 1;
346  }
347 
348  if (stats_opt & 0x04) {
349  odph_cli_log("cache_available is selected\n");
350  opt->cache_available = 1;
351  }
352 
353  if (stats_opt & 0x02) {
354  odph_cli_log("cache_alloc_ops is selected\n");
355  opt->cache_alloc_ops = 1;
356  }
357 
358  if (stats_opt & 0x01) {
359  odph_cli_log("cache_free_ops is selected\n");
360  opt->cache_free_ops = 1;
361  }
362 }
363 
364 /* Parse argument for subpools option -s or --subpools */
365 static int subpools_str_to_id(char *str, int *num_subpools/*out*/, int *subpools/*out*/)
366 {
367  int i;
368  long id;
369  const char *token;
370  char *saveptr;
371  const char *delim = "[,]";
372 
373  /* Only one subpool is given */
374  if (!strstr(str, "[")) {
375  *num_subpools = 1;
376 
377  if (str_to_long(str, &id, 10))
378  return -1;
379  subpools[0] = (int)id;
380  return 0;
381  }
382 
383  token = strtok_r(str, delim, &saveptr);
384  if (token == NULL) {
385  odph_cli_log("Invalid option argument: %s\n", str);
386  return -1;
387  }
388  if (str_to_long(token, &id, 10))
389  return -1;
390  subpools[0] = (int)id;
391 
392  for (i = 1; i < EM_MAX_SUBPOOLS; i++) {
393  token = strtok_r(NULL, delim, &saveptr);
394  if (token == NULL)
395  break;
396 
397  if (str_to_long(token, &id, 10))
398  return -1;
399  subpools[i] = (int)id;
400  }
401 
402  if (token/*Not break from loop*/ && strtok_r(NULL, delim, &saveptr)) {
403  odph_cli_log("Too many subpools, maximum number is: %d\n", EM_MAX_SUBPOOLS);
404  return -1;
405  }
406 
407  *num_subpools = i;
408  return 0;
409 }
410 
411 static void
412 print_em_subpools_stats(em_pool_t pool, const int subpools[], int num_subpools,
413  const em_pool_stats_opt_t *opt)
414 {
415  core_log_fn_set(cli_log);
416  core_vlog_fn_set(cli_vlog);
417 
418  if (opt)
419  subpools_stats_selected_print(pool, subpools, num_subpools, opt);
420  else
421  subpools_stats_print(pool, subpools, num_subpools);
422 
423  core_log_fn_set(NULL);
424  core_vlog_fn_set(NULL);
425 }
426 
427 static void print_subpools_stats(char *arg_subpools)
428 {
429  long pool_id;
430  char *saveptr;
431  em_pool_t pool;
432  int num_subpools;
433  char *str_subpools;
434  const char *str_stats_opt;
435  const char *pool_str;
436  int subpools[EM_MAX_SUBPOOLS];
437  const char *delim = ":";
438  em_pool_stats_opt_t opt = {0};
439 
440  pool_str = strtok_r(arg_subpools, delim, &saveptr);
441  if (pool_str == NULL) {
442  odph_cli_log("Invalid optarg: %s\n", arg_subpools);
443  return;
444  }
445 
446  if (str_to_long(pool_str, &pool_id, 16))
447  return;
448 
449  /*pool_id = 0 --> EM_POOL_UNDEF*/
450  if (!pool_id) {
451  odph_cli_log("Invalid pool id: %d\n", pool_id);
452  return;
453  }
454  pool = (em_pool_t)(uintptr_t)pool_id;
455 
456  str_subpools = strtok_r(NULL, delim, &saveptr);
457  if (str_subpools == NULL) {
458  odph_cli_log("Invalid optarg: %s (subpool IDs are missing)\n", arg_subpools);
459  return;
460  }
461 
462  if (subpools_str_to_id(str_subpools, &num_subpools, subpools))
463  return;
464 
465  str_stats_opt = strtok_r(NULL, delim, &saveptr);
466  /* No stats opt, then print all statistic counters */
467  if (str_stats_opt == NULL) {
468  print_em_subpools_stats(pool, subpools, num_subpools, NULL);
469  } else {
470  str_to_opt(str_stats_opt, &opt);
471  print_em_subpools_stats(pool, subpools, num_subpools, &opt);
472  }
473 }
474 
475 static void print_em_pool_stats_help(void)
476 {
477  const char *usage = "Usage: em_pool_stats [OPTION]\n"
478  "Print EM pool statistics\n"
479  "\n"
480  "Options:\n"
481  " -i, --id <pool id [:stats opt]>\tPrint statistics of <pool id>\n"
482  " -n, --name <pool name [:stats opt]>\tPrint statistics of <pool name>\n"
483  " -s, --subpools <pool:[subpool ids] [:stats opt]>\tPrint statistics of subpools\n"
484  " -h, --help\tDisplay this help\n\n"
485  "Note stats opt is optional, when not given, it prints statistics from\n"
486  "em_pool_stats(), namely all statistic counters. When it is given,\n"
487  "this command prints selected counters from em_pool_stats_selected().\n"
488  "stats opt here uses one byte to select the counters to be read. One\n"
489  "bit in stats opt selects one counter. MSB represents 'available' and\n"
490  "LSB represents 'cache_free_ops'. For example, stats_opt=0x88 selects\n"
491  "the 'available' and 'total_ops' statistic counters.\n\n"
492  "Example:\n"
493  " em_pool_stats -i 0x1\n"
494  " em_pool_stats -i 0x1:0x88\n";
495 
496  odph_cli_log(usage);
497 }
498 
499 static void print_pool_stats(char *optarg_str, bool is_id)
500 {
501  long pool_id;
502  char *saveptr;
503  em_pool_t pool;
504  const char *str_opt;
505  const char *pool_str;
506  const char *delim = ":";
507  em_pool_stats_opt_t opt = {0};
508 
509  /* Parse string containing pool ID or pool name */
510  pool_str = strtok_r(optarg_str, delim, &saveptr);
511  if (pool_str == NULL) {
512  odph_cli_log("Invalid optarg_str: %s\n", optarg_str);
513  return;
514  }
515 
516  if (is_id) {
517  if (str_to_long(pool_str, &pool_id, 16))
518  return;
519 
520  /*pool_id = 0 --> EM_POOL_UNDEF*/
521  if (!pool_id) {
522  odph_cli_log("Invalid pool id: %d\n", pool_id);
523  return;
524  }
525  pool = (em_pool_t)(uintptr_t)pool_id;
526  } else {
527  pool = pool_find(pool_str);
528  }
529 
530  /* Parse string for statistic counter options */
531  str_opt = strtok_r(NULL, delim, &saveptr);
532  if (str_opt == NULL) {
533  /* stats opt is missing, then print all statistic counters */
534  print_em_pool_stats(pool, is_id ? NULL : pool_str, NULL);
535  } else {
536  str_to_opt(str_opt, &opt);
537  print_em_pool_stats(pool, is_id ? NULL : pool_str, &opt);
538  }
539 }
540 
541 static void cmd_em_pool_stats(int argc, char *argv[])
542 {
543  /* Command em_pool_stats takes maximum 2 arguments */
544  const int max_args = 2;
545 
546  if (argc == 0) {
547  odph_cli_log("Please specify pool or subpool ids!\n");
548  print_em_pool_stats_help();
549  return;
550  } else if (argc > max_args) {
551  odph_cli_log("Error: extra parameter given to command!\n");
552  return;
553  }
554 
555  /* Unlike getopt, optparse does not require an argument count as input to
556  * indicate the number of arguments in argv. Instead, it uses NULL pointer
557  * to decide the end of argument array argv.
558  *
559  * argv here contains only CLI command options. To emulate a real command,
560  * argv_new is constructed to include command name.
561  */
562  argc += 1/*Cmd str "em_pool_stats"*/ + 1/*Terminating NULL pointer*/;
563  char *argv_new[argc];
564  char cmd[MAX_CMD_LEN] = "em_pool_stats";
565 
566  argv_new[0] = cmd;
567  for (int i = 1; i < argc - 1; i++)
568  argv_new[i] = argv[i - 1];
569  argv_new[argc - 1] = NULL; /*Terminating NULL pointer*/
570 
571  int option;
572  struct optparse_long longopts[] = {
573  {"id", 'i', OPTPARSE_REQUIRED},
574  {"name", 'n', OPTPARSE_REQUIRED},
575  {"subpools", 's', OPTPARSE_REQUIRED},
576  {"help", 'h', OPTPARSE_NONE},
577  {0}
578  };
579  struct optparse options;
580 
581  optparse_init(&options, argv_new);
582  options.permute = 0;
583  while (1) {
584  option = optparse_long(&options, longopts, NULL);
585  if (option == -1) /* No more options */
586  break;
587 
588  switch (option) {
589  case 'i':
590  print_pool_stats(options.optarg, true);
591  break;
592  case 'n':
593  print_pool_stats(options.optarg, false);
594  break;
595  case 's':
596  print_subpools_stats(options.optarg);
597  break;
598  case 'h':
599  print_em_pool_stats_help();
600  break;
601  case '?':
602  odph_cli_log("Error: %s\n", options.errmsg);
603  return;
604  default:
605  odph_cli_log("Unknown Error\n");
606  return;
607  }
608  }
609 }
610 
611 static void print_em_queue_help(void)
612 {
613  const char *usage = "Usage: em_queue_print [OPTION]\n"
614  "Print EM queue information\n"
615  "\n"
616  "Options:\n"
617  " -c, --capa\tPrint queue capabilities\n"
618  " -a, --all\tPrint info about all queues\n"
619  " -h, --help\tDisplay this help\n";
620  odph_cli_log(usage);
621 }
622 
623 static void print_em_queue_capa(void)
624 {
625  core_log_fn_set(cli_log);
626  core_vlog_fn_set(cli_vlog);
628  core_log_fn_set(NULL);
629  core_vlog_fn_set(NULL);
630 }
631 
632 static void print_em_queue_all(void)
633 {
634  core_log_fn_set(cli_log);
635  core_vlog_fn_set(cli_vlog);
637  core_log_fn_set(NULL);
638  core_vlog_fn_set(NULL);
639 }
640 
641 static void cmd_em_queue_print(int argc, char *argv[])
642 {
643  /* All current options accept no argument */
644  const int max_args = 1;
645 
646  /* When no argument is given, print info about all EM queues */
647  if (argc == 0) {
648  print_em_queue_all();
649  return;
650  } else if (argc > max_args) {
651  odph_cli_log("Error: extra parameter given to command!\n");
652  return;
653  }
654 
655  /* Unlike getopt, optparse does not require an argument count as input to
656  * indicate the number of arguments in argv. Instead, it uses NULL pointer
657  * to decide the end of argument array argv.
658  *
659  * argv here contains only CLI command options. To emulate a real command,
660  * argv_new is constructed to include command name.
661  */
662  argc += 1/*Cmd str "em_queue_print"*/ + 1/*Terminating NULL pointer*/;
663  char *argv_new[argc];
664  char cmd[MAX_CMD_LEN] = "em_queue_print";
665 
666  argv_new[0] = cmd;
667  for (int i = 1; i < argc - 1; i++)
668  argv_new[i] = argv[i - 1];
669  argv_new[argc - 1] = NULL; /*Terminating NULL pointer*/
670 
671  int option;
672  struct optparse_long longopts[] = {
673  {"capa", 'c', OPTPARSE_NONE},
674  {"all", 'a', OPTPARSE_NONE},
675  {"help", 'h', OPTPARSE_NONE},
676  {0}
677  };
678  struct optparse options;
679 
680  optparse_init(&options, argv_new);
681  options.permute = 0;
682  while (1) {
683  option = optparse_long(&options, longopts, NULL);
684  if (option == -1) /* No more options */
685  break;
686 
687  switch (option) {
688  case 'c':
689  print_em_queue_capa();
690  break;
691  case 'a':
692  print_em_queue_all();
693  break;
694  case 'h':
695  print_em_queue_help();
696  break;
697  case '?':
698  odph_cli_log("Error: %s\n", options.errmsg);
699  return;
700  default:
701  odph_cli_log("Unknown Error\n");
702  return;
703  }
704  }
705 }
706 
707 static void print_em_qgrp_help(void)
708 {
709  const char *usage = "Usage: em_qgrp_print [OPTION]\n"
710  "Print EM queue group information\n"
711  "\n"
712  "Options:\n"
713  " -a, --all(default)\tPrint info about all EM queue groups\n"
714  " -i, --id <qgrp id>\tPrint the queue info of <qgrp id>\n"
715  " -n, --name <qgrp name> \tPrint the queue info of <qgrp name>\n"
716  " -h, --help\tDisplay this help\n";
717  odph_cli_log(usage);
718 }
719 
720 static void print_em_qgrp_all(void)
721 {
722  core_log_fn_set(cli_log);
723  core_vlog_fn_set(cli_vlog);
725  core_log_fn_set(NULL);
726  core_vlog_fn_set(NULL);
727 }
728 
729 static void print_em_qgrp_queues(const em_queue_group_t qgrp, const char *name)
730 {
731  if (qgrp == EM_QUEUE_GROUP_UNDEF) {
732  if (name)
733  odph_cli_log("Error: can't find queue group %s!\n", name);
734  else
735  odph_cli_log("Error: can't find queue group %" PRI_QGRP "!\n", qgrp);
736  return;
737  }
738 
739  core_log_fn_set(cli_log);
740  core_vlog_fn_set(cli_vlog);
742  core_log_fn_set(NULL);
743  core_vlog_fn_set(NULL);
744 }
745 
746 static void cmd_em_qgrp_print(int argc, char *argv[])
747 {
748  /* em_qgrp_print takes maximum 2 arguments */
749  const int max_args = 2;
750 
751  /* When no argument is given, print all EM queue group info */
752  if (argc == 0) {
753  print_em_qgrp_all();
754  return;
755  } else if (argc > max_args) {
756  odph_cli_log("Error: extra parameter given to command!\n");
757  return;
758  }
759 
760  /* Unlike getopt, optparse does not require an argument count as input to
761  * indicate the number of arguments in argv. Instead, it uses NULL pointer
762  * to decide the end of argument array argv.
763  *
764  * argv here contains only CLI command options. To emulate a real command,
765  * argv_new is constructed to include command name.
766  */
767  argc += 1/*Cmd str "em_qgrp_print"*/ + 1/*Terminating NULL pointer*/;
768  char *argv_new[argc];
769  char cmd[MAX_CMD_LEN] = "em_qgrp_print";
770 
771  argv_new[0] = cmd;
772  for (int i = 1; i < argc - 1; i++)
773  argv_new[i] = argv[i - 1];
774  argv_new[argc - 1] = NULL; /*Terminating NULL pointer*/
775 
776  em_queue_group_t qgrp;
777  int option;
778  struct optparse_long longopts[] = {
779  {"all", 'a', OPTPARSE_NONE},
780  {"id", 'i', OPTPARSE_REQUIRED},
781  {"name", 'n', OPTPARSE_REQUIRED},
782  {"help", 'h', OPTPARSE_NONE},
783  {0}
784  };
785  struct optparse options;
786 
787  optparse_init(&options, argv_new);
788  options.permute = 0;
789  while (1) {
790  option = optparse_long(&options, longopts, NULL);
791 
792  if (option == -1)
793  break; /* No more options */
794 
795  switch (option) {
796  case 'a':
797  print_em_qgrp_all();
798  break;
799  case 'i':
800  qgrp = (em_queue_group_t)(uintptr_t)(int)strtol(options.optarg, NULL, 0);
801  print_em_qgrp_queues(qgrp, NULL);
802  break;
803  case 'n':
804  qgrp = em_queue_group_find(options.optarg);
805  print_em_qgrp_queues(qgrp, options.optarg);
806  break;
807  case 'h':
808  print_em_qgrp_help();
809  break;
810  case '?':
811  odph_cli_log("Error: %s\n", options.errmsg);
812  return;
813  default:
814  odph_cli_log("Unknown Error\n");
815  return;
816  }
817  }
818 }
819 
820 static void cmd_em_core_print(int argc, char *argv[])
821 {
822  (void)argv;
823  /* Print EM core map */
824  if (argc == 0) {
825  core_log_fn_set(cli_log);
826  core_vlog_fn_set(cli_vlog);
827  print_core_map_info();
828  core_log_fn_set(NULL);
829  core_vlog_fn_set(NULL);
830  } else {
831  odph_cli_log("Error: extra parameter given to command!\n");
832  }
833 }
834 
835 static void print_em_eo_help(void)
836 {
837  const char *usage = "Usage: em_eo_print [OPTION]\n"
838  "Print EO information\n"
839  "\n"
840  "Options:\n"
841  " -a, --all\tPrint all EO info\n"
842  " -i, --id <eo id>\tPrint info about all queues of <eo id>\n"
843  " -n, --name <eo name>\tPrint info about all queues of <eo name>\n"
844  " -h, --help\tDisplay this help\n";
845 
846  odph_cli_log(usage);
847 }
848 
849 static void print_em_eo_all(void)
850 {
851  core_log_fn_set(cli_log);
852  core_vlog_fn_set(cli_vlog);
854  core_log_fn_set(NULL);
855  core_vlog_fn_set(NULL);
856 }
857 
858 static void print_em_eo(const em_eo_t eo, const char *name)
859 {
860  if (eo == EM_EO_UNDEF) {
861  if (name)
862  odph_cli_log("Error: can't find EO %s\n", name);
863  else
864  odph_cli_log("Error: can't find EO %" PRI_EO "\n", eo);
865  return;
866  }
867 
868  core_log_fn_set(cli_log);
869  core_vlog_fn_set(cli_vlog);
871  core_log_fn_set(NULL);
872  core_vlog_fn_set(NULL);
873 }
874 
875 static void cmd_em_eo_print(int argc, char *argv[])
876 {
877  /* em_eo_print takes maximum 2 arguments */
878  const int max_args = 2;
879 
880  /* When no argument is given, print all eo info */
881  if (argc == 0) {
882  print_em_eo_all();
883  return;
884  } else if (argc > max_args) {
885  odph_cli_log("Error: extra parameter given to command!\n");
886  return;
887  }
888 
889  /* Unlike getopt, optparse does not require an argument count as input to
890  * indicate the number of arguments in argv. Instead, it uses NULL pointer
891  * to decide the end of argument array argv.
892  *
893  * argv here contains only CLI command options. To emulate a real command,
894  * argv_new is constructed to include command name.
895  */
896  argc += 1/*Cmd str "em_eo_print"*/ + 1/*Terminating NULL pointer*/;
897  char *argv_new[argc];
898  char cmd[MAX_CMD_LEN] = "em_eo_print";
899 
900  argv_new[0] = cmd;
901  for (int i = 1; i < argc - 1; i++)
902  argv_new[i] = argv[i - 1];
903  argv_new[argc - 1] = NULL; /*Terminating NULL pointer*/
904 
905  em_eo_t eo;
906  int option;
907  struct optparse_long longopts[] = {
908  {"all", 'a', OPTPARSE_NONE},
909  {"id", 'i', OPTPARSE_REQUIRED},
910  {"name", 'n', OPTPARSE_REQUIRED},
911  {"help", 'h', OPTPARSE_NONE},
912  {0}
913  };
914  struct optparse options;
915 
916  optparse_init(&options, argv_new);
917  options.permute = 0;
918  while (1) {
919  option = optparse_long(&options, longopts, NULL);
920  if (option == -1) /* No more options */
921  break;
922 
923  switch (option) {
924  case 'a':
925  print_em_eo_all();
926  break;
927  case 'i':
928  eo = (em_eo_t)(uintptr_t)(int)strtol(options.optarg, NULL, 0);
929  print_em_eo(eo, NULL);
930  break;
931  case 'n':
932  eo = em_eo_find(options.optarg);
933  print_em_eo(eo, options.optarg);
934  break;
935  case 'h':
936  print_em_eo_help();
937  break;
938  case '?':
939  odph_cli_log("Error: %s\n", options.errmsg);
940  return;
941  default:
942  odph_cli_log("Unknown Error\n");
943  return;
944  }
945  }
946 }
947 
948 static void print_em_agrp_help(void)
949 {
950  const char *usage = "Usage: em_agrp_print [OPTION]\n"
951  "Print info about atomic groups\n"
952  "\n"
953  "Options:\n"
954  " -a, --all\tPrint info about all atomic groups\n"
955  " -i, --id <ag id>\tPrint info about all queues of <ag id>\n"
956  " -n, --name <ag name>\tPrint info about all queues of <ag name>\n"
957  " -h, --help\tDisplay this help\n";
958 
959  odph_cli_log(usage);
960 }
961 
962 static void print_em_agrp_all(void)
963 {
964  core_log_fn_set(cli_log);
965  core_vlog_fn_set(cli_vlog);
967  core_log_fn_set(NULL);
968  core_vlog_fn_set(NULL);
969 }
970 
971 static void print_em_agrp(em_atomic_group_t ag, const char *ag_name)
972 {
973  if (ag == EM_ATOMIC_GROUP_UNDEF) {
974  if (ag_name)
975  odph_cli_log("Error: can't find atomic group %s\n", ag_name);
976  else
977  odph_cli_log("Error: can't find atomic group %" PRI_AGRP "\n", ag);
978  return;
979  }
980 
981  core_log_fn_set(cli_log);
982  core_vlog_fn_set(cli_vlog);
984  core_log_fn_set(NULL);
985  core_vlog_fn_set(NULL);
986 }
987 
988 static void cmd_em_agrp_print(int argc, char *argv[])
989 {
990  /* em_agrp_print takes maximum 2 arguments */
991  const int max_args = 2;
992 
993  /* When no argument is given, print info about all atomic groups */
994  if (argc == 0) {
995  print_em_agrp_all();
996  return;
997  } else if (argc > max_args) {
998  odph_cli_log("Error: extra parameter given to command!\n");
999  return;
1000  }
1001 
1002  /* Unlike getopt, optparse does not require an argument count as input to
1003  * indicate the number of arguments in argv. Instead, it uses NULL pointer
1004  * to decide the end of argument array argv.
1005  *
1006  * argv here contains only CLI command options. To emulate a real command,
1007  * argv_new is constructed to include command name.
1008  */
1009  argc += 1/*Cmd name "em_agrp_print"*/ + 1/*Terminating NULL pointer*/;
1010  char *argv_new[argc];
1011  char cmd[MAX_CMD_LEN] = "em_agrp_print";
1012 
1013  argv_new[0] = cmd;
1014  for (int i = 1; i < argc - 1; i++)
1015  argv_new[i] = argv[i - 1];
1016  argv_new[argc - 1] = NULL; /*Terminating NULL pointer*/
1017 
1018  em_atomic_group_t ag;
1019  int option;
1020  struct optparse_long longopts[] = {
1021  {"all", 'a', OPTPARSE_NONE},
1022  {"id", 'i', OPTPARSE_REQUIRED},
1023  {"name", 'n', OPTPARSE_REQUIRED},
1024  {"help", 'h', OPTPARSE_NONE},
1025  {0}
1026  };
1027  struct optparse options;
1028 
1029  optparse_init(&options, argv_new);
1030  options.permute = 0;
1031 
1032  while (1) {
1033  option = optparse_long(&options, longopts, NULL);
1034 
1035  if (option == -1)
1036  break;
1037 
1038  switch (option) {
1039  case 'a':
1040  print_em_agrp_all();
1041  break;
1042  case 'i':
1043  ag = (em_atomic_group_t)(uintptr_t)(int)strtol(options.optarg, NULL, 0);
1044  print_em_agrp(ag, NULL);
1045  break;
1046  case 'n':
1047  ag = em_atomic_group_find(options.optarg);
1048  print_em_agrp(ag, options.optarg);
1049  break;
1050  case 'h':
1051  print_em_agrp_help();
1052  break;
1053  case '?':
1054  odph_cli_log("Error: %s\n", options.errmsg);
1055  return;
1056  default:
1057  odph_cli_log("Unknown Error\n");
1058  return;
1059  }
1060  }
1061 }
1062 
1063 static void cmd_em_egrp_print(int argc, char *argv[])
1064 {
1065  (void)argv;
1066  /* When no argument is given, print info about all event groups */
1067  if (argc == 0) {
1068  core_log_fn_set(cli_log);
1069  core_vlog_fn_set(cli_vlog);
1071  core_log_fn_set(NULL);
1072  core_vlog_fn_set(NULL);
1073  } else {
1074  odph_cli_log("Error: extra parameter given to command!\n");
1075  }
1076 }
1077 
1078 static int cli_register_em_commands(void)
1079 {
1080  /* Register em commands */
1081  if (odph_cli_register_command("em_agrp_print", cmd_em_agrp_print,
1082  "[a|i <ag id>|n <ag name>|h]")) {
1083  EM_LOG(EM_LOG_ERR, "Registering EM command em_agrp_print failed.\n");
1084  return -1;
1085  }
1086 
1087  if (odph_cli_register_command("em_eo_print", cmd_em_eo_print,
1088  "[a|i <eo id>|n <eo name>|h]")) {
1089  EM_LOG(EM_LOG_ERR, "Registering EM command em_eo_print failed.\n");
1090  return -1;
1091  }
1092 
1093  if (odph_cli_register_command("em_egrp_print", cmd_em_egrp_print, "")) {
1094  EM_LOG(EM_LOG_ERR, "Registering EM cmd em_egrp_print failed.\n");
1095  return -1;
1096  }
1097 
1098  if (odph_cli_register_command("em_info_print", cmd_em_info_print,
1099  "[a|p|c|h]")) {
1100  EM_LOG(EM_LOG_ERR, "Registering EM command em_info_print failed.\n");
1101  return -1;
1102  }
1103 
1104  if (odph_cli_register_command("em_pool_print", cmd_em_pool_print,
1105  "[a|i <pool id>|n <pool name>|h]")) {
1106  EM_LOG(EM_LOG_ERR, "Registering EM command em_pool_print failed.\n");
1107  return -1;
1108  }
1109 
1110  if (odph_cli_register_command("em_pool_stats", cmd_em_pool_stats,
1111  "[i<pool id>|n<pool name>|s<pool id:[subpool ids]>[:o]|h]")) {
1112  EM_LOG(EM_LOG_ERR, "Registering EM command em_pool_stats failed.\n");
1113  return -1;
1114  }
1115 
1116  if (odph_cli_register_command("em_queue_print", cmd_em_queue_print,
1117  "[a|c|h]")) {
1118  EM_LOG(EM_LOG_ERR, "Registering EM command em_queue_print failed.\n");
1119  return -1;
1120  }
1121 
1122  if (odph_cli_register_command("em_qgrp_print", cmd_em_qgrp_print,
1123  "[a|i <qgrp id>|n <qgrp name>|h]")) {
1124  EM_LOG(EM_LOG_ERR, "Registering EM command em_qgrp_print failed.\n");
1125  return -1;
1126  }
1127 
1128  if (odph_cli_register_command("em_core_print", cmd_em_core_print, "")) {
1129  EM_LOG(EM_LOG_ERR, "Registering EM command em_core_print failed.\n");
1130  return -1;
1131  }
1132 
1133  return 0;
1134 }
1135 
1136 static int read_config_file(void)
1137 {
1138  /* Conf option: cli.enable - runtime enable/disable cli */
1139  const char *cli_conf = "cli.enable";
1140  bool cli_enable = false;
1141  int ret = em_libconfig_lookup_bool(&em_shm->libconfig, cli_conf,
1142  &cli_enable);
1143 
1144  if (unlikely(!ret)) {
1145  EM_LOG(EM_LOG_ERR, "Config option '%s' not found\n", cli_conf);
1146  return -1;
1147  }
1148 
1149  EM_PRINT("EM CLI config:\n");
1150  /* store & print the value */
1151  em_shm->opt.cli.enable = (int)cli_enable;
1152  EM_PRINT(" %s: %s(%d)\n", cli_conf, cli_enable ? "true" : "false",
1153  cli_enable);
1154 
1155  cli_conf = "cli.ip_addr";
1156  ret = em_libconfig_lookup_string(&em_shm->libconfig, cli_conf,
1157  &em_shm->opt.cli.ip_addr);
1158  if (unlikely(!ret)) {
1159  EM_LOG(EM_LOG_ERR, "Config option '%s' not found\n", cli_conf);
1160  return -1;
1161  }
1162  EM_PRINT(" %s: %s\n", cli_conf, em_shm->opt.cli.ip_addr);
1163 
1164  cli_conf = "cli.port";
1165  ret = em_libconfig_lookup_int(&em_shm->libconfig, cli_conf,
1166  &em_shm->opt.cli.port);
1167  if (unlikely(!ret)) {
1168  EM_LOG(EM_LOG_ERR, "Config option '%s' not found\n", cli_conf);
1169  return -1;
1170  }
1171  EM_PRINT(" %s: %d\n", cli_conf, em_shm->opt.cli.port);
1172 
1173  return 0;
1174 }
1175 
1176 static int cli_shm_setup(void)
1177 {
1178  if (cli_shm != NULL) {
1179  EM_LOG(EM_LOG_ERR, "EM CLI shared memory ptr already set!\n");
1180  return -1;
1181  }
1182 
1183  /*
1184  * Reserve the CLI shared memory once at start-up.
1185  */
1186  uint32_t flags = 0;
1187  odp_shm_capability_t shm_capa;
1188  int ret = odp_shm_capability(&shm_capa);
1189 
1190  if (ret) {
1191  EM_LOG(EM_LOG_ERR, "shm capability error:%d\n", ret);
1192  return -1;
1193  }
1194 
1195  /* No huge pages needed for the CLI shm */
1196  if (shm_capa.flags & ODP_SHM_NO_HP)
1197  flags |= ODP_SHM_NO_HP;
1198 
1199  odp_shm_t shm = odp_shm_reserve("em_cli", sizeof(em_cli_shm_t),
1200  ODP_CACHE_LINE_SIZE, flags);
1201 
1202  if (shm == ODP_SHM_INVALID) {
1203  EM_LOG(EM_LOG_ERR, "EM CLI shared memory reservation failed!\n");
1204  return -1;
1205  }
1206 
1207  cli_shm = odp_shm_addr(shm);
1208 
1209  if (cli_shm == NULL) {
1210  EM_LOG(EM_LOG_ERR, "EM CLI shared memory ptr NULL!\n");
1211  return -1;
1212  }
1213 
1214  memset(cli_shm, 0, sizeof(em_cli_shm_t));
1215 
1216  /* Store shm handle, can be used in stop_em_cli() to free the memory */
1217  cli_shm->this_shm = shm;
1218 
1219  return 0;
1220 }
1221 
1222 static int cli_shm_lookup(void)
1223 {
1224  odp_shm_t shm;
1225  em_cli_shm_t *shm_addr;
1226 
1227  /* Lookup the EM shared memory on each EM-core */
1228  shm = odp_shm_lookup("em_cli");
1229  if (shm == ODP_SHM_INVALID) {
1230  EM_LOG(EM_LOG_ERR, "Shared memory lookup failed!\n");
1231  return -1;
1232  }
1233 
1234  shm_addr = odp_shm_addr(shm);
1235  if (!shm_addr) {
1236  EM_LOG(EM_LOG_ERR, "Shared memory ptr NULL\n");
1237  return -1;
1238  }
1239 
1240  if (em_shm->conf.process_per_core && cli_shm == NULL)
1241  cli_shm = shm_addr;
1242 
1243  if (shm_addr != cli_shm) {
1244  EM_LOG(EM_LOG_ERR, "CLI shared memory init fails: cli_shm:%p != shm_addr:%p\n",
1245  cli_shm, shm_addr);
1246  return -1;
1247  }
1248 
1249  return 0;
1250 }
1251 
1252 static int cli_shm_free(void)
1253 {
1254  if (odp_shm_free(cli_shm->this_shm)) {
1255  EM_LOG(EM_LOG_ERR, "Error: odp_shm_free() failed\n");
1256  return -1;
1257  }
1258 
1259  /* Set cli_shm = NULL to allow a new call to cli_shm_setup() */
1260  cli_shm = NULL;
1261 
1262  return 0;
1263 }
1264 
1265 static int cli_thr_fn(__attribute__((__unused__)) void *arg)
1266 {
1267  init_ext_thread();
1268 
1269  /* Run CLI server. */
1270  if (odph_cli_run()) {
1271  EM_LOG(EM_LOG_ERR, "Failed to start CLI server.\n");
1272  exit(EXIT_FAILURE);
1273  }
1274 
1275  /* em_term_core_cli() */
1276  return 0;
1277 }
1278 
1279 /*
1280  * Run EM CLI server
1281  *
1282  * When executing this function, the CLI is accepting client connections and
1283  * running commands from a client, if one is connected.
1284  *
1285  * @return EM_OK if successful.
1286  */
1287 static em_status_t run_em_cli(void)
1288 {
1289  /* Prepare CLI parameters */
1290  odph_cli_param_t cli_param = {0};
1291 
1292  odph_cli_param_init(&cli_param);
1293  cli_param.hostname = "EM-ODP";
1294  cli_param.address = em_shm->opt.cli.ip_addr;
1295  cli_param.port = (uint16_t)em_shm->opt.cli.port;
1296 
1297  /* Initialize CLI helper */
1298  if (odph_cli_init(&cli_param)) {
1299  EM_LOG(EM_LOG_ERR, "Error: odph_cli_init() failed.\n");
1300  return EM_ERR_LIB_FAILED;
1301  }
1302 
1303  /* Register EM CLI commands */
1304  if (cli_register_em_commands()) {
1305  EM_LOG(EM_LOG_ERR, "Error: cli_register_em_commands() failed.\n");
1306  return EM_ERR_LIB_FAILED;
1307  }
1308 
1309  /* Create thread to run CLI server */
1310  odp_cpumask_t cpumask;
1311  odph_thread_common_param_t thr_common;
1312  odph_thread_param_t thr_param;
1313  odp_instance_t instance;
1314 
1315  if (odp_cpumask_default_control(&cpumask, 1) != 1) {
1316  EM_LOG(EM_LOG_ERR, "Failed to get default CPU mask.\n");
1317  return EM_ERR_LIB_FAILED;
1318  }
1319 
1320  if (odp_instance(&instance)) {
1321  EM_LOG(EM_LOG_ERR, "Failed to get odp instance.\n");
1322  return EM_ERR_LIB_FAILED;
1323  }
1324 
1325  odph_thread_common_param_init(&thr_common);
1326  thr_common.instance = instance;
1327  thr_common.cpumask = &cpumask;
1328  thr_common.thread_model = 0; /* 0: Use pthread for the CLI */
1329 
1330  odph_thread_param_init(&thr_param);
1331  thr_param.thr_type = ODP_THREAD_CONTROL;
1332  thr_param.start = cli_thr_fn;
1333  thr_param.arg = NULL;
1334 
1335  /* Set up EM CLI shared memory */
1336  if (cli_shm_setup()) {
1337  EM_LOG(EM_LOG_ERR, "Error: cli_shm_setup() failed.\n");
1338  return EM_ERR_ALLOC_FAILED;
1339  }
1340 
1341  EM_PRINT("Starting CLI server on %s:%d\n", cli_param.address, cli_param.port);
1342 
1343  /* Create EM CLI server thread and store the thread ID to be used in
1344  * stop_em_cli() to wait for the thread to exit.
1345  */
1346  if (odph_thread_create(&cli_shm->em_cli_thread, &thr_common,
1347  &thr_param, 1) != 1) {
1348  EM_LOG(EM_LOG_ERR, "Failed to create CLI server thread.\n");
1349  cli_shm_free();
1350  return -1;
1351  }
1352 
1353  return EM_OK;
1354 }
1355 
1356 /*
1357  * Stop EM CLI server
1358  *
1359  * Stop accepting new client connections and disconnect any connected client.
1360  *
1361  * @return EM_OK if successful.
1362  */
1363 static em_status_t stop_em_cli(void)
1364 {
1365  if (odph_cli_stop()) {
1366  EM_LOG(EM_LOG_ERR, "Failed to stop CLI.\n");
1367  goto error;
1368  }
1369 
1370  if (odph_thread_join(&cli_shm->em_cli_thread, 1) != 1) {
1371  EM_LOG(EM_LOG_ERR, "Failed to join server thread.\n");
1372  goto error;
1373  }
1374 
1375  if (odph_cli_term()) {
1376  EM_LOG(EM_LOG_ERR, "Failed to terminate CLI.\n");
1377  goto error;
1378  }
1379 
1380  cli_shm_free();
1381  EM_PRINT("\nCLI server terminated!\n");
1382 
1383  return EM_OK;
1384 
1385 error:
1386  cli_shm_free();
1387  return EM_ERR_LIB_FAILED;
1388 }
1389 
1390 em_status_t emcli_init(void)
1391 {
1392  em_status_t stat = EM_OK;
1393 
1394  /* Store libconf options to em_shm */
1395  if (read_config_file())
1396  return EM_ERR_LIB_FAILED;
1397 
1398  if (em_shm->opt.cli.enable) {
1399  stat = run_em_cli();
1400 
1401  if (stat != EM_OK) {
1402  EM_LOG(EM_LOG_ERR, "%s(): run_em_cli() failed:%" PRI_STAT "\n",
1403  __func__, stat);
1404  }
1405  }
1406 
1407  return stat;
1408 }
1409 
1411 {
1412  if (!em_shm->opt.cli.enable)
1413  return EM_OK;
1414 
1415  int ret = cli_shm_lookup();
1416 
1417  if (ret)
1418  return EM_ERR_LIB_FAILED;
1419 
1420  return EM_OK;
1421 }
1422 
1423 em_status_t emcli_term(void)
1424 {
1425  em_status_t stat = EM_OK;
1426 
1427  if (em_shm->opt.cli.enable) {
1428  stat = stop_em_cli();
1429 
1430  if (stat != EM_OK) {
1431  EM_LOG(EM_LOG_ERR, "%s(): stop_em_cli() failed:%" PRI_STAT "\n",
1432  __func__, stat);
1433  }
1434  }
1435 
1436  return stat;
1437 }
1438 
1440 {
1441  return EM_OK;
1442 }
1443 
1444 #else /* EM_CLI */
1445 /* Dummy functions for building without odph_cli and libcli support */
1447 {
1448  return EM_OK;
1449 }
1450 
1452 {
1453  return EM_OK;
1454 }
1455 
1457 {
1458  return EM_OK;
1459 }
1460 
1462 {
1463  return EM_OK;
1464 }
1465 
1466 #endif /* EM_CLI */
EM_QUEUE_GROUP_UNDEF
#define EM_QUEUE_GROUP_UNDEF
Definition: event_machine_types.h:127
em_pool_stats_opt_t::available
uint64_t available
Definition: event_machine_pool.h:102
EM_OK
#define EM_OK
Definition: event_machine_types.h:329
emcli_init
em_status_t emcli_init(void)
Initialize the EM CLI (if enabled)
Definition: em_cli.c:1446
em_pool_stats_opt_t::alloc_ops
uint64_t alloc_ops
Definition: event_machine_pool.h:105
emcli_init_local
em_status_t emcli_init_local(void)
Initialize the EM CLI locally on an EM core (if enabled)
Definition: em_cli.c:1451
queue_group_queues_print
void queue_group_queues_print(em_queue_group_t qgrp)
Print info about all queues belonging to the given queue group.
Definition: em_queue_group.c:1553
eo_info_print_all
void eo_info_print_all(void)
Definition: em_eo.c:1253
init_ext_thread
em_status_t init_ext_thread(void)
Definition: em_init.c:90
em_pool_stats_opt_t::cache_alloc_ops
uint64_t cache_alloc_ops
Definition: event_machine_pool.h:120
em_atomic_group_find
em_atomic_group_t em_atomic_group_find(const char *name)
Definition: event_machine_atomic_group.c:367
PRI_POOL
#define PRI_POOL
Definition: event_machine_hw_types.h:62
print_queue_capa
void print_queue_capa(void)
Definition: em_queue.c:1472
PRI_EO
#define PRI_EO
Definition: event_machine_types.h:97
eo_queue_info_print
void eo_queue_info_print(em_eo_t eo)
Definition: em_eo.c:1326
event_group_info_print
void event_group_info_print(void)
Definition: em_event_group.c:126
em_pool_info_print_all
void em_pool_info_print_all(void)
Definition: event_machine_pool.c:313
em_pool_stats_opt_t::free_ops
uint64_t free_ops
Definition: event_machine_pool.h:111
EM_ERR_ALLOC_FAILED
@ EM_ERR_ALLOC_FAILED
Definition: event_machine_hw_types.h:287
EM_ERR_LIB_FAILED
@ EM_ERR_LIB_FAILED
Definition: event_machine_hw_types.h:291
EM_EO_UNDEF
#define EM_EO_UNDEF
Definition: event_machine_types.h:95
optparse
Definition: optparse.h:55
core_vlog_fn_set
void core_vlog_fn_set(em_vlog_func_t func)
Definition: em_init.c:83
print_em_info
void print_em_info(void)
Definition: em_info.c:426
print_atomic_group_queues
void print_atomic_group_queues(em_atomic_group_t ag)
Definition: em_atomic_group.c:401
em_pool_stats_opt_t::cache_free_ops
uint64_t cache_free_ops
Definition: event_machine_pool.h:123
PRI_AGRP
#define PRI_AGRP
Definition: event_machine_types.h:158
print_atomic_group_info
void print_atomic_group_info(void)
Definition: em_atomic_group.c:330
queue_group_info_print_all
void queue_group_info_print_all(void)
Print EM queue group info.
Definition: em_queue_group.c:1491
em_shm_t::libconfig
libconfig_t libconfig
Definition: em_mem.h:146
em_queue_group_find
em_queue_group_t em_queue_group_find(const char *name)
Definition: event_machine_queue_group.c:236
core_log_fn_set
void core_log_fn_set(em_log_func_t func)
Definition: em_init.c:76
em_pool_stats_opt_t::total_ops
uint64_t total_ops
Definition: event_machine_pool.h:114
emcli_term
em_status_t emcli_term(void)
Terminate the EM CLI (if enabled)
Definition: em_cli.c:1456
em_pool_stats_opt_t::cache_available
uint64_t cache_available
Definition: event_machine_pool.h:117
emcli_term_local
em_status_t emcli_term_local(void)
Terminate the EM CLI locally on an EM core (if enabled)
Definition: em_cli.c:1461
optparse_long
Definition: optparse.h:71
__attribute__
__attribute__((weak)) em_status_t event_send_device(em_event_t event
em_pool_stats_opt_t::alloc_fails
uint64_t alloc_fails
Definition: event_machine_pool.h:108
em_status_t
uint32_t em_status_t
Definition: event_machine_types.h:321
PRI_QGRP
#define PRI_QGRP
Definition: event_machine_types.h:129
EM_ATOMIC_GROUP_UNDEF
#define EM_ATOMIC_GROUP_UNDEF
Definition: event_machine_types.h:156
em_shm
em_shm_t * em_shm
Definition: event_machine_init.c:41
em_include.h
em_pool_stats_opt_t
Definition: event_machine_pool.h:98
em_log_level_t
em_log_level_t
Definition: event_machine_hw_types.h:318
print_queue_info
void print_queue_info(void)
Definition: em_queue.c:1749
EM_POOL_UNDEF
#define EM_POOL_UNDEF
Definition: event_machine_hw_types.h:60
EM_MAX_SUBPOOLS
#define EM_MAX_SUBPOOLS
The number of subpools in each EM pool. The subpool is a pool with buffers of only one size.
Definition: event_machine_hw_types.h:254
em_eo_find
em_eo_t em_eo_find(const char *name)
Definition: event_machine_eo.c:265