1*d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*d30ea906Sjfb8856606  * Copyright(c) 2015 Intel Corporation
3a9643ea8Slogwang  */
4a9643ea8Slogwang 
5a9643ea8Slogwang #ifndef LTHREAD_DIAG_H_
6a9643ea8Slogwang #define LTHREAD_DIAG_H_
7a9643ea8Slogwang 
82bfe3f2eSlogwang #ifdef __cplusplus
92bfe3f2eSlogwang extern "C" {
102bfe3f2eSlogwang #endif
112bfe3f2eSlogwang 
12a9643ea8Slogwang #include <stdint.h>
13a9643ea8Slogwang #include <inttypes.h>
14a9643ea8Slogwang 
15a9643ea8Slogwang #include <rte_log.h>
16a9643ea8Slogwang #include <rte_common.h>
17a9643ea8Slogwang 
18a9643ea8Slogwang #include "lthread_api.h"
19a9643ea8Slogwang #include "lthread_diag_api.h"
20a9643ea8Slogwang 
21a9643ea8Slogwang extern diag_callback diag_cb;
22a9643ea8Slogwang 
23a9643ea8Slogwang extern const char *diag_event_text[];
24a9643ea8Slogwang extern uint64_t diag_mask;
25a9643ea8Slogwang 
26a9643ea8Slogwang /* max size of name strings */
27a9643ea8Slogwang #define LT_MAX_NAME_SIZE 64
28a9643ea8Slogwang 
29a9643ea8Slogwang #if LTHREAD_DIAG
30a9643ea8Slogwang #define DISPLAY_OBJCACHE_QUEUES 1
31a9643ea8Slogwang 
32a9643ea8Slogwang /*
33a9643ea8Slogwang  * Generate a diagnostic trace or event in the case where an object is created.
34a9643ea8Slogwang  *
35a9643ea8Slogwang  * The value returned by the callback is stored in the object.
36a9643ea8Slogwang  *
37a9643ea8Slogwang  * @ param obj
38a9643ea8Slogwang  *  pointer to the object that was created
39a9643ea8Slogwang  * @ param ev
40a9643ea8Slogwang  *  the event code
41a9643ea8Slogwang  *
42a9643ea8Slogwang  */
43a9643ea8Slogwang #define DIAG_CREATE_EVENT(obj, ev) do {					\
44a9643ea8Slogwang 	struct lthread *ct = RTE_PER_LCORE(this_sched)->current_lthread;\
45a9643ea8Slogwang 	if ((BIT(ev) & diag_mask) && (ev < LT_DIAG_EVENT_MAX)) {	\
46a9643ea8Slogwang 		(obj)->diag_ref = (diag_cb)(rte_rdtsc(),		\
47a9643ea8Slogwang 					ct,				\
48a9643ea8Slogwang 					(ev),				\
49a9643ea8Slogwang 					0,				\
50a9643ea8Slogwang 					diag_event_text[(ev)],		\
51a9643ea8Slogwang 					(uint64_t)obj,			\
52a9643ea8Slogwang 					0);				\
53a9643ea8Slogwang 	}								\
54a9643ea8Slogwang } while (0)
55a9643ea8Slogwang 
56a9643ea8Slogwang /*
57a9643ea8Slogwang  * Generate a diagnostic trace event.
58a9643ea8Slogwang  *
59a9643ea8Slogwang  * @ param obj
60a9643ea8Slogwang  *  pointer to the lthread, cond or mutex object
61a9643ea8Slogwang  * @ param ev
62a9643ea8Slogwang  *  the event code
63a9643ea8Slogwang  * @ param p1
64a9643ea8Slogwang  *  object specific value ( see lthread_diag_api.h )
65a9643ea8Slogwang  * @ param p2
66a9643ea8Slogwang  *  object specific value ( see lthread_diag_api.h )
67a9643ea8Slogwang  */
68a9643ea8Slogwang #define DIAG_EVENT(obj, ev, p1, p2) do {				\
69a9643ea8Slogwang 	struct lthread *ct = RTE_PER_LCORE(this_sched)->current_lthread;\
70a9643ea8Slogwang 	if ((BIT(ev) & diag_mask) && (ev < LT_DIAG_EVENT_MAX)) {	\
71a9643ea8Slogwang 		(diag_cb)(rte_rdtsc(),					\
72a9643ea8Slogwang 				ct,					\
73a9643ea8Slogwang 				ev,					\
74a9643ea8Slogwang 				(obj)->diag_ref,			\
75a9643ea8Slogwang 				diag_event_text[(ev)],			\
76a9643ea8Slogwang 				(uint64_t)(p1),				\
77a9643ea8Slogwang 				(uint64_t)(p2));			\
78a9643ea8Slogwang 	}								\
79a9643ea8Slogwang } while (0)
80a9643ea8Slogwang 
81a9643ea8Slogwang #define DIAG_COUNT_DEFINE(x) rte_atomic64_t count_##x
82a9643ea8Slogwang #define DIAG_COUNT_INIT(o, x) rte_atomic64_init(&((o)->count_##x))
83a9643ea8Slogwang #define DIAG_COUNT_INC(o, x) rte_atomic64_inc(&((o)->count_##x))
84a9643ea8Slogwang #define DIAG_COUNT_DEC(o, x) rte_atomic64_dec(&((o)->count_##x))
85a9643ea8Slogwang #define DIAG_COUNT(o, x) rte_atomic64_read(&((o)->count_##x))
86a9643ea8Slogwang 
87a9643ea8Slogwang #define DIAG_USED
88a9643ea8Slogwang 
89a9643ea8Slogwang #else
90a9643ea8Slogwang 
91a9643ea8Slogwang /* no diagnostics configured */
92a9643ea8Slogwang 
93a9643ea8Slogwang #define DISPLAY_OBJCACHE_QUEUES 0
94a9643ea8Slogwang 
95a9643ea8Slogwang #define DIAG_CREATE_EVENT(obj, ev)
96a9643ea8Slogwang #define DIAG_EVENT(obj, ev, p1, p)
97a9643ea8Slogwang 
98a9643ea8Slogwang #define DIAG_COUNT_DEFINE(x)
99a9643ea8Slogwang #define DIAG_COUNT_INIT(o, x) do {} while (0)
100a9643ea8Slogwang #define DIAG_COUNT_INC(o, x) do {} while (0)
101a9643ea8Slogwang #define DIAG_COUNT_DEC(o, x) do {} while (0)
102a9643ea8Slogwang #define DIAG_COUNT(o, x) 0
103a9643ea8Slogwang 
104a9643ea8Slogwang #define DIAG_USED __rte_unused
105a9643ea8Slogwang 
106a9643ea8Slogwang #endif				/* LTHREAD_DIAG */
1072bfe3f2eSlogwang 
1082bfe3f2eSlogwang #ifdef __cplusplus
1092bfe3f2eSlogwang }
1102bfe3f2eSlogwang #endif
1112bfe3f2eSlogwang 
112a9643ea8Slogwang #endif				/* LTHREAD_DIAG_H_ */
113