telemetry: introduce infrastructure
[dpdk.git] / lib / librte_telemetry / rte_telemetry.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4
5 #include <unistd.h>
6 #include <pthread.h>
7
8 #include <rte_eal.h>
9 #include <rte_ethdev.h>
10 #include <rte_metrics.h>
11 #include <rte_option.h>
12
13 #include "rte_telemetry.h"
14 #include "rte_telemetry_internal.h"
15
16 #define SLEEP_TIME 10
17
18 static telemetry_impl *static_telemetry;
19
20 static int32_t
21 rte_telemetry_run(void *userdata)
22 {
23         struct telemetry_impl *telemetry = userdata;
24
25         if (telemetry == NULL) {
26                 TELEMETRY_LOG_WARN("TELEMETRY could not be initialised");
27                 return -1;
28         }
29
30         return 0;
31 }
32
33 static void
34 *rte_telemetry_run_thread_func(void *userdata)
35 {
36         int ret;
37         struct telemetry_impl *telemetry = userdata;
38
39         if (telemetry == NULL) {
40                 TELEMETRY_LOG_ERR("%s passed a NULL instance", __func__);
41                 pthread_exit(0);
42         }
43
44         while (telemetry->thread_status) {
45                 rte_telemetry_run(telemetry);
46                 ret = usleep(SLEEP_TIME);
47                 if (ret < 0)
48                         TELEMETRY_LOG_ERR("Calling thread could not be put to sleep");
49         }
50         pthread_exit(0);
51 }
52
53 int32_t __rte_experimental
54 rte_telemetry_init()
55 {
56         int ret;
57         pthread_attr_t attr;
58         const char *telemetry_ctrl_thread = "telemetry";
59
60         if (static_telemetry) {
61                 TELEMETRY_LOG_WARN("TELEMETRY structure already initialised");
62                 return -EALREADY;
63         }
64
65         static_telemetry = calloc(1, sizeof(struct telemetry_impl));
66         if (static_telemetry == NULL) {
67                 TELEMETRY_LOG_ERR("Memory could not be allocated");
68                 return -ENOMEM;
69         }
70
71         static_telemetry->socket_id = rte_socket_id();
72         rte_metrics_init(static_telemetry->socket_id);
73
74         ret = pthread_attr_init(&attr);
75         if (ret != 0) {
76                 TELEMETRY_LOG_ERR("Pthread attribute init failed");
77                 return -EPERM;
78         }
79
80         ret = rte_ctrl_thread_create(&static_telemetry->thread_id,
81                 telemetry_ctrl_thread, &attr, rte_telemetry_run_thread_func,
82                 (void *)static_telemetry);
83         static_telemetry->thread_status = 1;
84
85         if (ret < 0) {
86                 ret = rte_telemetry_cleanup();
87                 if (ret < 0)
88                         TELEMETRY_LOG_ERR("TELEMETRY cleanup failed");
89                 return -EPERM;
90         }
91
92         return 0;
93 }
94
95 int32_t __rte_experimental
96 rte_telemetry_cleanup(void)
97 {
98         struct telemetry_impl *telemetry = static_telemetry;
99         telemetry->thread_status = 0;
100         pthread_join(telemetry->thread_id, NULL);
101         free(telemetry);
102         static_telemetry = NULL;
103         return 0;
104 }
105
106 int telemetry_log_level;
107
108 static struct rte_option option = {
109         .opt_str = "--telemetry",
110         .cb = &rte_telemetry_init,
111         .enabled = 0
112 };
113
114 RTE_INIT(rte_telemetry_register)
115 {
116         telemetry_log_level = rte_log_register("lib.telemetry");
117         if (telemetry_log_level >= 0)
118                 rte_log_set_level(telemetry_log_level, RTE_LOG_ERR);
119
120         rte_option_register(&option);
121 }