libxcoder  3.5.1
ni_rsrc_mon_logan.c
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * Copyright (C) 2022 NETINT Technologies
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18  * SOFTWARE.
19  *
20  ******************************************************************************/
21 
22 /*!*****************************************************************************
23  *
24  * \file ni_rsrc_mon_logan.c
25  *
26  * @date April 1, 2018
27  *
28  * \brief NETINT T4XX resource monitor utility program
29  *
30  * @author
31  *
32  ******************************************************************************/
33 
34 #if defined(__linux__) || defined(__APPLE__)
35 #include <unistd.h>
36 #include <signal.h>
37 #include <sys/file.h> /* For flock constants */
38 #endif
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 
43 #include <errno.h>
44 #include <time.h>
45 #include <ctype.h>
46 #include <string.h>
47 #include "ni_defs_logan.h"
48 #include "ni_device_api_logan.h"
49 #include "ni_rsrc_api_logan.h"
50 #include "ni_rsrc_priv_logan.h"
51 #include "ni_util_logan.h"
52 
53 #ifdef __ANDROID__
54 #include <cutils/properties.h>
55 
56 #define LOG_TAG "ni_rsrc_mon_logan"
57 
58 #endif
59 
60 #ifdef _WIN32
61 #include "ni_getopt_logan.h"
62 
63 static BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
64 {
66  return TRUE;
87 }
88 
89 #elif defined(__linux__)
90 void setup_signal_handler(void);
91 
92 
93 /*!******************************************************************************
94  * \brief
95  *
96  * \param
97  *
98  * \return
99  *******************************************************************************/
100 void sig_handler(int sig)
101 {
102  if (sig == SIGTERM || sig == SIGINT)
103  {
105  }
106  else if (sig == SIGHUP)
107  {
108  printf("SIGHUP, reloading p_config ? ");
109  setup_signal_handler();
110  }
111 }
112 
113 /*!******************************************************************************
114  * \brief
115  *
116  * \param
117  *
118  * \return
119  *******************************************************************************/
120 void setup_signal_handler(void)
121 {
122  if (signal(SIGTERM, sig_handler) == SIG_ERR ||
123  signal(SIGHUP, sig_handler) == SIG_ERR ||
124  signal(SIGINT, sig_handler) == SIG_ERR)
125  {
126  fprintf(stderr, "Error %d: signal handler setup\n", NI_ERRNO);
127  }
128 }
129 
130 /*!******************************************************************************
131  * \brief get linux numa_node
132  *
133  * \param[in] const char *device_name
134  *
135  * \return int atoi(cmd_ret)
136  *******************************************************************************/
137 int get_numa_node(const char *device_name)
138 {
139  int ret = -1;
140  FILE *cmd_fp;
141  char *ptr = NULL;
142  char cmd[128] = {0};
143  char cmd_ret[64] = {0};
144 
145  if(!device_name)
146  {
147  return ret;
148  }
149  ptr = (char *)(device_name + 5);
150  snprintf(cmd, sizeof(cmd) - 1, "cat /sys/block/%s/device/*/numa_node",ptr);
151  cmd_fp = popen(cmd, "r");
152  if (!cmd_fp)
153  {
154  return ret;
155  }
156  if (fgets(cmd_ret, sizeof(cmd_ret)/sizeof(cmd_ret[0]), cmd_fp) == NULL)
157  {
158  LRETURN;
159  }
160  ret = atoi(cmd_ret);
161 
162 END:
163  pclose(cmd_fp);
164  return ret;
165 }
166 
167 #endif //defined(__linux__)
168 
169 
170 /*!******************************************************************************
171  * \brief convert number from argv input to integer if safe
172  *
173  * \param char *numArray
174  *
175  * \return int atoi(numArray)
176  *******************************************************************************/
177 int argToI(char *numArray)
178 {
179  int i;
180 
181  if( !numArray )
182  {
183  return 0;
184  }
185 
186  const size_t len = strlen(numArray);
187 
188  for (i = 0; i < len; i++)
189  {
190  if (!isdigit(numArray[i]))
191  {
192  fprintf(stderr, "invalid, ABORTING\n");
193  abort();
194  }
195  }
196 
197  return len == i ? atoi(numArray) : 0;
198 }
199 
200 /*!******************************************************************************
201  * \brief compare two int32_t for qsort
202  *
203  * \param[in] const void *a
204  * \param[in] const void *b
205  *
206  * \return int atoi(numArray)
207  *******************************************************************************/
208 int compareInt32_t(const void *a, const void *b)
209 {
210  if ( *(int32_t*)a < *(int32_t*)b ) return -1;
211  if ( *(int32_t*)a == *(int32_t*)b ) return 0;
212  if ( *(int32_t*)a > *(int32_t*)b ) return 1;
213  return 0;
214 }
215 
216 /*!******************************************************************************
217  * \brief print performance data for either decoder or encoder
218  *
219  * \param[in] ni_logan_device_type_t module_type
220  * \param[in] ni_logan_device_queue_t *coders
221  * \param[in] ni_logan_session_context_t *sessionCtxt
222  *
223  * \return ni_logan_retcode_t rc
224  *******************************************************************************/
226  ni_logan_device_queue_t *coders,
227  ni_logan_session_context_t *sessionCtxt,
228  int outformattype)
229 {
230  int i; // used in later FOR-loop when compiled without c99
231  int module_count = 0;
232  char module_name[8];
233  int *module_id_arr = NULL;
234  int best_load_module_id = -1;
235  ni_logan_device_context_t *p_device_context = NULL;
236 
237  if (module_type == NI_LOGAN_DEVICE_TYPE_DECODER)
238  {
239  module_count = coders->decoders_cnt;
240  snprintf(module_name, sizeof(module_name), "decoder");
241  module_id_arr = (int *)malloc(sizeof(int) * module_count);
242  if(!module_id_arr)
243  {
244  fprintf(stderr, "ERROR %d: Failed to allocate memory for ni_logan_rsrc_mon print_perf()",
245  NI_ERRNO);
246  return;
247  }
248  memcpy(module_id_arr, coders->decoders, sizeof(int) * module_count);
249  }
250  else if (module_type == NI_LOGAN_DEVICE_TYPE_ENCODER)
251  {
252  module_count = coders->encoders_cnt;
253  snprintf(module_name, sizeof(module_name), "encoder");
254  module_id_arr = (int *)malloc(sizeof(int) * module_count);
255  if(!module_id_arr)
256  {
257  fprintf(stderr, "ERROR %d: Failed to allocate memory for ni_logan_rsrc_mon print_perf()",
258  NI_ERRNO);
259  return;
260  }
261  memcpy(module_id_arr, coders->encoders, sizeof(int) * module_count);
262  }
263  else
264  {
265  fprintf(stderr, "ERROR: Unknown device type: %d\n", module_type);
266  return;
267  }
268 
269  // First module ID in coders->decoders/encoders is of lowest load
270  if (!module_id_arr)
271  {
272  fprintf(stderr, "ERROR %d: Failed to allocate memory for ni_logan_rsrc_mon print_perf()",
273  NI_ERRNO);
274  return;
275  }
276  else
277  {
278  memcpy((void*)&best_load_module_id, module_id_arr, sizeof(int));
279  }
280 
281  if (outformattype == 0)
282  {
283  printf("Num %ss: %d\n", module_name, module_count);
284  }
285 
286  // sort module IDs used
287  qsort(module_id_arr, module_count, sizeof(int), compareInt32_t);
288 
289  // Print performance info headings
290  if (outformattype == 0)
291  {
292  printf("%-4s %-5s %-4s %-10s %-4s %-4s %-14s %-20s\n", "BEST", "INDEX",
293  "LOAD", "MODEL_LOAD", "MEM", "INST", "DEVICE", "NAMESPACE");
294  }
295  else if (outformattype == 2 || outformattype == 3)
296  {
297  if (module_type == NI_LOGAN_DEVICE_TYPE_DECODER)
298  {
299  printf("{\n \"decoders\": [\n");
300  }
301  else if (module_type == NI_LOGAN_DEVICE_TYPE_ENCODER)
302  {
303  printf(" \"encoders\": [\n");
304  }
305  }
307  for (i = 0; i < module_count; i++)
308  {
309  p_device_context = ni_logan_rsrc_get_device_context(module_type, module_id_arr[i]);
310 
312  if (p_device_context)
313  {
314  sessionCtxt->blk_io_handle = ni_logan_device_open(p_device_context->p_device_info->blk_name,
315  &sessionCtxt->max_nvme_io_size);
316  sessionCtxt->device_handle = sessionCtxt->blk_io_handle;
317 
318  // Check device can be opened
319  if (NI_INVALID_DEVICE_HANDLE == sessionCtxt->device_handle)
320  {
321  fprintf(stderr, "Error open device %s, blk device %s\n",
322  p_device_context->p_device_info->dev_name,
323  p_device_context->p_device_info->blk_name);
324  ni_logan_rsrc_free_device_context(p_device_context);
325  continue;
326  }
327 
328 #ifdef _WIN32
329  sessionCtxt->event_handle = ni_logan_create_event();
330  if (NI_INVALID_EVENT_HANDLE == sessionCtxt->event_handle)
331  {
332  ni_logan_rsrc_free_device_context(p_device_context);
333  ni_logan_device_close(sessionCtxt->device_handle);
334  fprintf(stderr, "ERROR %d: print_perf() create envet\n", NI_ERRNO);
335  continue;
336  }
337 #endif
338 
339  // Check dec/enc can be queried
340  sessionCtxt->hw_id = p_device_context->p_device_info->hw_id;
341  if (NI_LOGAN_RETCODE_SUCCESS != ni_logan_device_session_query(sessionCtxt, module_type))
342  {
343  ni_logan_device_close(sessionCtxt->device_handle);
344 #ifdef _WIN32
345  ni_logan_close_event(sessionCtxt->event_handle);
346 #endif
347  fprintf(stderr, "Error query %s %s %s.%d\n", module_name,
348  p_device_context->p_device_info->dev_name,
349  p_device_context->p_device_info->blk_name,
350  p_device_context->p_device_info->hw_id);
351  ni_logan_rsrc_free_device_context(p_device_context);
352  continue;
353  }
354  ni_logan_device_close(sessionCtxt->device_handle);
355 #ifdef _WIN32
356  ni_logan_close_event(sessionCtxt->event_handle);
357 #endif
358 
359  if (0 == sessionCtxt->load_query.total_contexts)
360  {
361  sessionCtxt->load_query.current_load = 0;
362  }
363 
364  // Evaluate if module is of best load
365  char best_load_print[2] = " ";
366  if (best_load_module_id == p_device_context->p_device_info->module_id)
367  {
368  strncpy(best_load_print, "L", 1);
369  }
370 
371  // Print performance info row
372  if(outformattype == 0)
373  {
374  printf("%s%s%s %-5d %-4d %-10d %-4d %-4d %-14s %-20s\n", best_load_print, " ", " ",
375  p_device_context->p_device_info->module_id,
376  sessionCtxt->load_query.current_load,
377  sessionCtxt->load_query.fw_model_load,
378  sessionCtxt->load_query.fw_video_mem_usage,
379  sessionCtxt->load_query.total_contexts,
380  p_device_context->p_device_info->dev_name,
381  p_device_context->p_device_info->blk_name);
382  }
383  else if (outformattype == 1)
384  {
385  printf("{\n"
386  " \"%s\" : [\n"
387  " {\n"
388  " \"%s\" : %d,\n"
389  " \"%s\" : \"%s\",\n"
390  " \"%s\" : %d,\n"
391  " \"%s\" : %d,\n"
392  " \"%s\" : %d,\n"
393  " \"%s\" : %d,\n"
394  " \"%s\" : %d,\n"
395  " \"%s\" : \"%s\",\n"
396  " \"%s\" : \"%s\",\n"
397 #ifdef __linux__
398  " \"%s\" : %d\n"
399 #endif
400  " }\n"
401  " ]\n"
402  "}\n",
403  module_name, "NUMBER", module_count, "BEST", best_load_print,
404  "INDEX", p_device_context->p_device_info->module_id,
405  "LOAD", sessionCtxt->load_query.current_load,
406  "MODEL_LOAD", sessionCtxt->load_query.fw_model_load,
407  "MEM", sessionCtxt->load_query.fw_video_mem_usage,
408  "INST", sessionCtxt->load_query.total_contexts,
409  "DEVICE", p_device_context->p_device_info->dev_name,
410  "NAMESPACE", p_device_context->p_device_info->blk_name
411 #ifdef __linux__
412  ,"NUMA_NODE",get_numa_node(p_device_context->p_device_info->blk_name)
413 #endif
414  );
415  }
416  else if (outformattype == 3)
417  {
418  printf( " {\n"
419  " \"%s\" : %d,\n"
420  " \"%s\" : \"%s\",\n"
421  " \"%s\" : %d,\n"
422  " \"%s\" : %d,\n"
423  " \"%s\" : %d,\n"
424  " \"%s\" : %d,\n"
425  " \"%s\" : %d,\n"
426  " \"%s\" : \"%s\",\n"
427  " \"%s\" : \"%s\",\n"
428 #ifdef __linux__
429  " \"%s\" : %d,\n"
430 #endif
431  " \"%s\" : %d,\n"
432  " \"%s\" : \"%s\"\n"
433  " }",
434  "NUMBER", module_count, "BEST", best_load_print,
435  "INDEX", p_device_context->p_device_info->module_id,
436  "LOAD", sessionCtxt->load_query.current_load,
437  "MODEL_LOAD", sessionCtxt->load_query.fw_model_load,
438  "MEM", sessionCtxt->load_query.fw_video_mem_usage,
439  "INST", sessionCtxt->load_query.total_contexts,
440  "DEVICE", p_device_context->p_device_info->dev_name,
441  "NAMESPACE", p_device_context->p_device_info->blk_name
442 #ifdef __linux__
443  ,"NUMA_NODE",get_numa_node(p_device_context->p_device_info->blk_name)
444 #endif
445  ,"TEMP", sessionCtxt->composite_temperature,
446  "POWER", "N/A"
447  );
448  if (i < module_count - 1)
449  {
450  printf(",\n");
451  }
452  else
453  {
454  printf("\n");
455  }
456  }
457  else
458  {
459  printf( " {\n"
460  " \"%s\" : %d,\n"
461  " \"%s\" : \"%s\",\n"
462  " \"%s\" : %d,\n"
463  " \"%s\" : %d,\n"
464  " \"%s\" : %d,\n"
465  " \"%s\" : %d,\n"
466  " \"%s\" : %d,\n"
467  " \"%s\" : \"%s\",\n"
468  " \"%s\" : \"%s\",\n"
469 #ifdef __linux__
470  " \"%s\" : %d\n"
471 #endif
472  " }",
473  "NUMBER", module_count, "BEST", best_load_print,
474  "INDEX", p_device_context->p_device_info->module_id,
475  "LOAD", sessionCtxt->load_query.current_load,
476  "MODEL_LOAD", sessionCtxt->load_query.fw_model_load,
477  "MEM", sessionCtxt->load_query.fw_video_mem_usage,
478  "INST", sessionCtxt->load_query.total_contexts,
479  "DEVICE", p_device_context->p_device_info->dev_name,
480  "NAMESPACE", p_device_context->p_device_info->blk_name
481 #ifdef __linux__
482  ,"NUMA_NODE",get_numa_node(p_device_context->p_device_info->blk_name)
483 #endif
484  );
485  if (i < module_count - 1)
486  {
487  printf(",\n");
488  }
489  else
490  {
491  printf("\n");
492  }
493  }
494  ni_logan_rsrc_free_device_context(p_device_context);
495  }
496  }
497 
498  if (outformattype == 2 || outformattype == 3)
499  {
500  if (module_type == NI_LOGAN_DEVICE_TYPE_DECODER)
501  {
502  printf(" ],\n");
503  }
504  else if (module_type == NI_LOGAN_DEVICE_TYPE_ENCODER)
505  {
506  printf(" ]\n}\n");
507  }
508  }
509  free(module_id_arr);
510  return;
511 }
512 
513 /*!******************************************************************************
514  * \brief
515  *
516  * \param
517  *
518  * \return
519  * 0 on success
520  * 1 on failure
521  *******************************************************************************/
522 int main(int argc, char *argv[])
523 {
524  int rc = 0;
525  int checkInterval;
526  int should_match_rev = 1;
527  int init_no_compat_check = 0;
528  int init_only_if_full_compat = 0;
529  enum outFormat
530  {
531  text,
532  json,
533  json1,
534  json2
535  } printFormat;
536  ni_logan_device_pool_t *p_device_pool = NULL;
537  ni_logan_device_queue_t *coders = NULL;
538  ni_logan_device_context_t *p_device_context = NULL;
539  ni_logan_session_context_t xCtxt = { 0 };
540  ni_log_level_t loglevel = NI_LOG_INFO;
541  time_t startTime = { 0 }, now = { 0 };
542  int timeout_seconds = 0;
543  struct tm *ltime = NULL;
544  char buf[64] = { 0 };
545  long long time_diff_hours, time_diff_minutes, time_diff_seconds;
546  int opt;
547  printFormat = text;
548  checkInterval = 0;
549  int refresh = 1;
550 
551 #ifdef _WIN32
552  SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
553 #elif defined(__linux__)
554  setup_signal_handler();
555 #endif
556 
557  // arg handling
558  while ((opt = getopt(argc, argv, "hvrcn:o:t:l:i")) != -1)
559  {
560  switch (opt)
561  {
562  case 'o':
563  // Output print format
564  if (!strcmp(optarg, "json"))
565  {
566  printFormat = json;
567  }
568  else if (!strcmp(optarg, "text"))
569  {
570  printFormat = text;
571  }
572  else if (!strcmp(optarg, "json1"))
573  {
574  printFormat = json1;
575  }
576  else if (!strcmp(optarg, "json2"))
577  {
578  printFormat = json2;
579  }
580  else
581  {
582  fprintf(stderr, "Error: unknown selection for outputFormat: %s\n", optarg);
583  return 1;
584  }
585  break;
586  case 'n':
587  // Output interval
588  checkInterval = atoi(optarg);
589  break;
590  case 'r':
591  init_no_compat_check = 1;
592  break;
593  case 'c':
594  init_only_if_full_compat = 1;
595  break;
596  case 't':
597  timeout_seconds = atoi(optarg);
598  printf("Timeout will be set %d\n", timeout_seconds);
599  break;
600  case 'l':
601  if (!strcmp(optarg, "none")) {
602  loglevel = NI_LOG_NONE;
603  } else if (!strcmp(optarg, "fatal")) {
604  loglevel = NI_LOG_FATAL;
605  } else if (!strcmp(optarg, "error")) {
606  loglevel = NI_LOG_ERROR;
607  } else if (!strcmp(optarg, "info")) {
608  loglevel = NI_LOG_INFO;
609  } else if (!strcmp(optarg, "debug")) {
610  loglevel = NI_LOG_DEBUG;
611  } else if (!strcmp(optarg, "trace")) {
612  loglevel = NI_LOG_TRACE;
613  } else {
614  fprintf(stderr, "unknown log level selected: %s", optarg);
615  return 1;
616  }
617  ni_log_set_level(loglevel);
618  break;
619  case 'i':
620  refresh = 0;
621  break;
622  case 'v':
623  printf("%s\n", NI_LOGAN_XCODER_REVISION);
624  return 0;
625  case 'h':
626  // help message
627  printf("-------- ni_rsrc_mon_logan v%s --------\n"
628  "The ni_rsrc_mon_logan program provides a real-time view of NETINT Logan T4XX \n"
629  "resources running on the system.\n"
630  "return 0 on success\n"
631  "return 1 on failure\n"
632  "Usage: sudo ni_rsrc_mon_logan [OPTIONS]\n"
633  "-o Output print format: text|json||json2\n"
634  "-n Specify reporting interval in one second interval.\n"
635  " If 0 or no selection, report only once.\n Default: 0\n"
636  "-r Init transcoder card resource regardless firmware release \n"
637  " version to libxcoder_logan version compatibility.\n"
638  " Default: only init cards with compatible firmware version.\n"
639  "-c Only init if all cards are fully compatible. Default is to init as many \n"
640  " fully and partially cards as possible."
641  "-t Set timeout time in seconds for device polling. Program will \n"
642  " exit with failure if timeout is reached without finding at \n"
643  " least one device. If 0 or no selection, poll indefinitely \n"
644  " until a T4XX device is found.\n"
645  " Default: 0\n"
646  "-l Set loglevel of libxcoder_logan API.\n"
647  " [none, fatal, error, info, debug, trace]\n"
648  " Default: info\n"
649  "-v Show libxcoder_logan version.\n"
650  "-i Do not refresh the devices list.\n"
651  "-h Open this help message.\n"
652  "\n"
653  "Reporting columns\n"
654  "BEST flag showing card of lowest realtime load and to be selected for \n"
655  " next auto allocated job\n"
656  "INDEX index number used by resource manager to identify the resource\n"
657  "LOAD realtime load\n"
658  "MODEL_LOAD estimated load based on framerate and resolution\n"
659  "INST number of job instances\n"
660  "DEVICE path to NVMe device file handle\n"
661  "NAMESPACE path to NVMe namespace file handle\n", NI_LOGAN_XCODER_REVISION);
662  return 0;
663  case '?':
664 #ifdef _WIN32
665  fprintf(stderr, "Option -o, -n, or -l require an argument, use option -h for help, "
666  "all other options are not supported.\n");
667  return 1;
668 #elif defined(__linux__)
669  if ((optopt == 'o') || (optopt == 'n') || (optopt == 'l'))
670  {
671  fprintf(stderr, "Option -%c requires an argument.\n", optopt);
672  return 1;
673  }
674  else if (isprint(optopt))
675  {
676  fprintf(stderr, "Unknown option `-%c'.\n", optopt);
677  return 1;
678  }
679  else
680  {
681  fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
682  return 1;
683  }
684 #endif
685  break;
686  default:
687  fprintf(stderr, "ABORTING\n");
688  abort();
689  }
690  }
691 
692  if (init_no_compat_check && init_only_if_full_compat)
693  {
694  fprintf(stderr, "Error: -r option cannot be used with -c option\n");
695  return 1;
696  }
697  if (init_no_compat_check)
698  {
699  should_match_rev = 0;
700  }
701  else if (init_only_if_full_compat)
702  {
703  should_match_rev = 2;
704  }
705 
706  if ((argc <= 2) && (optind == 1))
707  {
708  for (; optind < argc; optind++)
709  {
710  checkInterval = argToI(argv[optind]);
711  }
712  }
713 
714 #ifdef __ANDROID__
715  ni_log_set_log_tag(LOG_TAG);
716 #endif
717 
718  if (ni_logan_rsrc_init(should_match_rev,timeout_seconds) < 0)
719  {
720  fprintf(stderr, "Error access NI resource, quit ..\n");
721  return 1;
722  }
723 
724  p_device_pool = ni_logan_rsrc_get_device_pool();
725  if (!p_device_pool)
726  {
727  fprintf(stderr, "Error get Coders info ..\n");
728  return 1;
729  }
730 
732 
733  if (loglevel >= NI_LOG_INFO)
734  {
735  printf("**************************************************\n");
736  }
737 
738  startTime = time(NULL);
739 #ifdef __ANDROID__
740  system("chown mediacodec:mediacodec /dev/shm_netint/*");
741 #endif
743  {
744  now = time(NULL);
745  ltime = localtime(&now);
746  if (ltime)
747  {
748  strftime(buf, sizeof(buf), "%c", ltime);
749  }
750  time_diff_seconds = (long long)difftime(now, startTime);
751  time_diff_minutes = time_diff_seconds / 60;
752  time_diff_hours = time_diff_minutes / 60;
753 
754  if (refresh)
755  {
756  if (NI_LOGAN_RETCODE_SUCCESS != ni_logan_rsrc_refresh(should_match_rev))
757  {
758  printf("Error: resource pool records might be corrupted!!\n");
759  return 1;
760  }
761  }
762 
763  if (loglevel >= NI_LOG_INFO)
764  {
765  printf("%s up %02lld" ":%02lld" ":%02lld" " v%s\n", buf, time_diff_hours, time_diff_minutes % 60, time_diff_seconds % 60,
767  }
768 
771 #ifdef _WIN32
772  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval)
773  {
774  fprintf(stderr, "ERROR: Failed to obtain mutex: %p\n", p_device_pool->lock);
775  return 1;
776  }
777 #elif defined(__linux__)
778  if ( flock(p_device_pool->lock, LOCK_EX) )
779  {
780  fprintf(stderr, "Error flock() failed\n");
781  }
782 #endif
783 
784  coders = p_device_pool->p_device_queue;
785 
786 #ifdef _WIN32
787  ReleaseMutex((HANDLE)p_device_pool->lock);
788 #elif defined(__linux__)
789  if ( flock(p_device_pool->lock, LOCK_UN) )
790  {
791  fprintf(stderr, "Error flock() failed\n");
792  }
793 #endif
794 
795  print_perf(NI_LOGAN_DEVICE_TYPE_DECODER, coders, &xCtxt, printFormat);
796  print_perf(NI_LOGAN_DEVICE_TYPE_ENCODER, coders, &xCtxt, printFormat);
797 
798  if (loglevel >= NI_LOG_INFO)
799  {
800  printf("**************************************************\n");
801  }
802 
803  fflush(stderr);
804 
805  if (checkInterval == 0)
806  {
807  // run once
808  break;
809  }
810  ni_logan_usleep((int64_t)checkInterval * 1000 * 1000);
811  }
813  ni_logan_rsrc_free_device_pool(p_device_pool);
814 #ifdef __ANDROID__
815  system("chown mediacodec:mediacodec /dev/shm_netint/*");
816  system("chmod 777 /dev/block/nvme*");
817 #endif
818 
819  return 0;
820 }
Common NETINT definitions used by all modules.
@ NI_LOGAN_RETCODE_SUCCESS
#define END
#define NI_LOGAN_XCODER_REVISION
Definition: ni_defs_logan.h:62
#define NI_ERRNO
ni_logan_device_type_t
@ NI_LOGAN_DEVICE_TYPE_ENCODER
@ NI_LOGAN_DEVICE_TYPE_DECODER
#define LRETURN
ni_device_handle_t ni_logan_device_open(const char *p_dev, uint32_t *p_max_io_size_out)
Opens device and returnes device device_handle if successful.
ni_logan_retcode_t ni_logan_device_session_query(ni_logan_session_context_t *p_ctx, ni_logan_device_type_t device_type)
Query session data from the device - Currently not implemented If device_type is NI_LOGAN_DEVICE_TYPE...
void ni_logan_device_session_context_init(ni_logan_session_context_t *p_ctx)
Initialize already allocated session context to a known state.
void ni_logan_close_event(ni_event_handle_t event_handle)
Closes event and releases resources.
#define atoi(p_str)
void ni_logan_device_session_context_clear(ni_logan_session_context_t *p_ctx)
Clear already allocated session context to all zeros.
ni_event_handle_t ni_logan_create_event(void)
Create event and returnes event handle if successful.
void ni_logan_device_close(ni_device_handle_t device_handle)
Closes device and releases resources.
Main NETINT device API header file provides the ability to communicate with NI T-408 type hardware tr...
int getopt(int argc, char *argv[], const char *optstring)
int optopt
int optind
char * optarg
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
Definition: ni_log_logan.c:138
ni_log_level_t
Definition: ni_log_logan.h:60
@ NI_LOG_NONE
Definition: ni_log_logan.h:62
@ NI_LOG_DEBUG
Definition: ni_log_logan.h:66
@ NI_LOG_TRACE
Definition: ni_log_logan.h:67
@ NI_LOG_FATAL
Definition: ni_log_logan.h:63
@ NI_LOG_ERROR
Definition: ni_log_logan.h:64
@ NI_LOG_INFO
Definition: ni_log_logan.h:65
#define LOG_TAG
ni_logan_device_context_t * ni_logan_rsrc_get_device_context(ni_logan_device_type_t device_type, int guid)
Allocates and returns a pointer to ni_logan_device_context_t struct based on provided device_type and...
void ni_logan_rsrc_free_device_pool(ni_logan_device_pool_t *p_device_pool)
Free all resources taken by the device pool.
void ni_logan_rsrc_free_device_context(ni_logan_device_context_t *p_device_context)
Free previously allocated device context.
int ni_logan_rsrc_init(int should_match_rev, int timeout_seconds)
Initialize and create all resources required to work with NETINT NVMe transcoder devices....
ni_logan_retcode_t ni_logan_rsrc_refresh(int should_match_rev)
Scan and refresh all resources on the host, taking into account hot-plugged and pulled out cards.
ni_logan_device_pool_t * ni_logan_rsrc_get_device_pool(void)
Create and return the allocated ni_logan_device_pool_t struct.
Exported definitions related to resource management of NI T-408 devices.
int main(int argc, char *argv[])
int compareInt32_t(const void *a, const void *b)
compare two int32_t for qsort
int argToI(char *numArray)
convert number from argv input to integer if safe
void print_perf(ni_logan_device_type_t module_type, ni_logan_device_queue_t *coders, ni_logan_session_context_t *sessionCtxt, int outformattype)
print performance data for either decoder or encoder
uint32_t g_logan_xcoder_stop_process
Private definitions related to resource management of NI T-408 devices.
void ni_logan_usleep(int64_t usec)
Exported utility routines definition.
ni_logan_device_info_t * p_device_info
char dev_name[NI_LOGAN_MAX_DEVICE_NAME_LEN]
char blk_name[NI_LOGAN_MAX_DEVICE_NAME_LEN]
ni_logan_device_queue_t * p_device_queue
int32_t decoders[LOGAN_MAX_DEVICE_CNT]
int32_t encoders[LOGAN_MAX_DEVICE_CNT]
ni_logan_load_query_t load_query
ni_device_handle_t device_handle
ni_device_handle_t blk_io_handle