1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015 Intel Corporation
3  */
4 #ifndef LTHREAD_DIAG_API_H_
5 #define LTHREAD_DIAG_API_H_
6 
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 #include <stdint.h>
12 #include <inttypes.h>
13 
14 /*
15  * Enable diagnostics
16  * 0 = conditionally compiled out
17  * 1 = compiled in and maskable at run time, see below for details
18  */
19 #define LTHREAD_DIAG 0
20 
21 /**
22  *
23  * @file lthread_diag_api.h
24  *
25  * @warning
26  * @b EXPERIMENTAL: this API may change without prior notice
27  *
28  * lthread diagnostic interface
29  *
30  * If enabled via configuration file option ( tbd ) the lthread subsystem
31  * can generate selected trace information, either RTE_LOG  (INFO) messages,
32  * or else invoke a user supplied callback function when any of the events
33  * listed below occur.
34  *
35  * Reporting of events can be selectively masked, the bit position in the
36  * mask is determined by the corresponding event identifier listed below.
37  *
38  * Diagnostics are enabled by registering the callback function and mask
39  * using the API lthread_diagnostic_enable().
40  *
41  * Various interesting parameters are passed to the callback, including the
42  * time in cpu clks, the lthread id, the diagnostic event id, a user ref value,
43  * event text string, object being traced, and two context dependent parameters
44  * (p1 and p2). The meaning of the two parameters p1 and p2 depends on
45  * the specific event.
46  *
47  * The events LT_DIAG_LTHREAD_CREATE, LT_DIAG_MUTEX_CREATE and
48  * LT_DIAG_COND_CREATE are implicitly enabled if the event mask includes any of
49  * the LT_DIAG_LTHREAD_XXX, LT_DIAG_MUTEX_XXX or LT_DIAG_COND_XXX events
50  * respectively.
51  *
52  * These create events may also be included in the mask discreetly if it is
53  * desired to monitor only create events.
54  *
55  * @param  time
56  *  The time in cpu clks at which the event occurred
57  *
58  * @param  lthread
59  *  The current lthread
60  *
61  * @param diag_event
62  *  The diagnostic event id (bit position in the mask)
63  *
64  * @param  diag_ref
65  *
66  * For LT_DIAG_LTHREAD_CREATE, LT_DIAG_MUTEX_CREATE or LT_DIAG_COND_CREATE
67  * this parameter is not used and set to 0.
68  * All other events diag_ref contains the user ref value returned by the
69  * callback function when lthread is created.
70  *
71  * The diag_ref values assigned to mutex and cond var can be retrieved
72  * using the APIs lthread_mutex_diag_ref(), and lthread_cond_diag_ref()
73  * respectively.
74  *
75  * @param p1
76  *  see below
77  *
78  * @param p1
79  *  see below
80  *
81  * @returns
82  * For LT_DIAG_LTHREAD_CREATE, LT_DIAG_MUTEX_CREATE or LT_DIAG_COND_CREATE
83  * expects a user diagnostic ref value that will be saved in the lthread, mutex
84  * or cond var.
85  *
86  * For all other events return value is ignored.
87  *
88  *	LT_DIAG_SCHED_CREATE - Invoked when a scheduler is created
89  *		p1 = the scheduler that was created
90  *		p2 = not used
91  *		return value will be ignored
92  *
93  *	LT_DIAG_SCHED_SHUTDOWN - Invoked when a shutdown request is received
94  *		p1 = the scheduler to be shutdown
95  *		p2 = not used
96  *		return value will be ignored
97  *
98  *	LT_DIAG_LTHREAD_CREATE - Invoked when a thread is created
99  *		p1 = the lthread that was created
100  *		p2 = not used
101  *		return value will be stored in the lthread
102  *
103  *	LT_DIAG_LTHREAD_EXIT - Invoked when a lthread exits
104  *		p2 = 0 if the thread was already joined
105  *		p2 = 1 if the thread was not already joined
106  *		return val ignored
107  *
108  *	LT_DIAG_LTHREAD_JOIN - Invoked when a lthread exits
109  *		p1 = the lthread that is being joined
110  *		p2 = 0 if the thread was already exited
111  *		p2 = 1 if the thread was not already exited
112  *		return val ignored
113  *
114  *	LT_DIAG_LTHREAD_CANCELLED - Invoked when an lthread is cancelled
115  *		p1 = not used
116  *		p2 = not used
117  *		return val ignored
118  *
119  *	LT_DIAG_LTHREAD_DETACH - Invoked when an lthread is detached
120  *		p1 = not used
121  *		p2 = not used
122  *		return val ignored
123  *
124  *	LT_DIAG_LTHREAD_FREE - Invoked when an lthread is freed
125  *		p1 = not used
126  *		p2 = not used
127  *		return val ignored
128  *
129  *	LT_DIAG_LTHREAD_SUSPENDED - Invoked when an lthread is suspended
130  *		p1 = not used
131  *		p2 = not used
132  *		return val ignored
133  *
134  *	LT_DIAG_LTHREAD_YIELD - Invoked when an lthread explicitly yields
135  *		p1 = not used
136  *		p2 = not used
137  *		return val ignored
138  *
139  *	LT_DIAG_LTHREAD_RESCHEDULED - Invoked when an lthread is rescheduled
140  *		p1 = not used
141  *		p2 = not used
142  *		return val ignored
143  *
144  *	LT_DIAG_LTHREAD_RESUMED - Invoked when an lthread is resumed
145  *		p1 = not used
146  *		p2 = not used
147  *		return val ignored
148  *
149  *	LT_DIAG_LTHREAD_AFFINITY - Invoked when an lthread is affinitised
150  *		p1 = the destination lcore_id
151  *		p2 = not used
152  *		return val ignored
153  *
154  *	LT_DIAG_LTHREAD_TMR_START - Invoked when an lthread starts a timer
155  *		p1 = address of timer node
156  *		p2 = the timeout value
157  *		return val ignored
158  *
159  *	LT_DIAG_LTHREAD_TMR_DELETE - Invoked when an lthread deletes a timer
160  *		p1 = address of the timer node
161  *		p2 = 0 the timer and the was successfully deleted
162  *		p2 = not usee
163  *		return val ignored
164  *
165  *	LT_DIAG_LTHREAD_TMR_EXPIRED - Invoked when an lthread timer expires
166  *		p1 = address of scheduler the timer expired on
167  *		p2 = the thread associated with the timer
168  *		return val ignored
169  *
170  *	LT_DIAG_COND_CREATE - Invoked when a condition variable is created
171  *		p1 = address of cond var that was created
172  *		p2 = not used
173  *		return diag ref value will be stored in the condition variable
174  *
175  *	LT_DIAG_COND_DESTROY - Invoked when a condition variable is destroyed
176  *		p1 = not used
177  *		p2 = not used
178  *		return val ignored
179  *
180  *	LT_DIAG_COND_WAIT - Invoked when an lthread waits on a cond var
181  *		p1 = the address of the condition variable
182  *		p2 = not used
183  *		return val ignored
184  *
185  *	LT_DIAG_COND_SIGNAL - Invoked when an lthread signals a cond var
186  *		p1 = the address of the cond var
187  *		p2 = the lthread that was signalled, or error code
188  *		return val ignored
189  *
190  *	LT_DIAG_COND_BROADCAST - Invoked when an lthread broadcasts a cond var
191  *		p1 = the address of the condition variable
192  *		p2 = the lthread(s) that are signalled, or error code
193  *
194  *	LT_DIAG_MUTEX_CREATE - Invoked when a mutex is created
195  *		p1 = address of muex
196  *		p2 = not used
197  *		return diag ref value will be stored in the mutex variable
198  *
199  *	LT_DIAG_MUTEX_DESTROY - Invoked when a mutex is destroyed
200  *		p1 = address of mutex
201  *		p2 = not used
202  *		return val ignored
203  *
204  *	LT_DIAG_MUTEX_LOCK - Invoked when a mutex lock is obtained
205  *		p1 = address of mutex
206  *		p2 = function return value
207  *		return val ignored
208  *
209  *	LT_DIAG_MUTEX_BLOCKED  - Invoked when an lthread blocks on a mutex
210  *		p1 = address of mutex
211  *		p2 = function return value
212  *		return val ignored
213  *
214  *	LT_DIAG_MUTEX_TRYLOCK - Invoked when a mutex try lock is attempted
215  *		p1 = address of mutex
216  *		p2 = the function return value
217  *		return val ignored
218  *
219  *	LT_DIAG_MUTEX_UNLOCKED - Invoked when a mutex is unlocked
220  *		p1 = address of mutex
221  *		p2 = the thread that was unlocked, or error code
222  *		return val ignored
223  */
224 typedef uint64_t (*diag_callback) (uint64_t time, struct lthread *lt,
225 				  int diag_event, uint64_t diag_ref,
226 				const char *text, uint64_t p1, uint64_t p2);
227 
228 /*
229  * Set user diagnostic callback and mask
230  * If the callback function pointer is NULL the default
231  * callback handler will be restored.
232  */
233 void lthread_diagnostic_enable(diag_callback cb, uint64_t diag_mask);
234 
235 /*
236  * Set diagnostic mask
237  */
238 void lthread_diagnostic_set_mask(uint64_t mask);
239 
240 /*
241  * lthread diagnostic callback
242  */
243 enum lthread_diag_ev {
244 	/* bits 0 - 14 lthread flag group */
245 	LT_DIAG_LTHREAD_CREATE,		/* 00 mask 0x00000001 */
246 	LT_DIAG_LTHREAD_EXIT,		/* 01 mask 0x00000002 */
247 	LT_DIAG_LTHREAD_JOIN,		/* 02 mask 0x00000004 */
248 	LT_DIAG_LTHREAD_CANCEL,		/* 03 mask 0x00000008 */
249 	LT_DIAG_LTHREAD_DETACH,		/* 04 mask 0x00000010 */
250 	LT_DIAG_LTHREAD_FREE,		/* 05 mask 0x00000020 */
251 	LT_DIAG_LTHREAD_SUSPENDED,	/* 06 mask 0x00000040 */
252 	LT_DIAG_LTHREAD_YIELD,		/* 07 mask 0x00000080 */
253 	LT_DIAG_LTHREAD_RESCHEDULED,	/* 08 mask 0x00000100 */
254 	LT_DIAG_LTHREAD_SLEEP,		/* 09 mask 0x00000200 */
255 	LT_DIAG_LTHREAD_RESUMED,	/* 10 mask 0x00000400 */
256 	LT_DIAG_LTHREAD_AFFINITY,	/* 11 mask 0x00000800 */
257 	LT_DIAG_LTHREAD_TMR_START,	/* 12 mask 0x00001000 */
258 	LT_DIAG_LTHREAD_TMR_DELETE,	/* 13 mask 0x00002000 */
259 	LT_DIAG_LTHREAD_TMR_EXPIRED,	/* 14 mask 0x00004000 */
260 	/* bits 15 - 19 conditional variable flag group */
261 	LT_DIAG_COND_CREATE,		/* 15 mask 0x00008000 */
262 	LT_DIAG_COND_DESTROY,		/* 16 mask 0x00010000 */
263 	LT_DIAG_COND_WAIT,		/* 17 mask 0x00020000 */
264 	LT_DIAG_COND_SIGNAL,		/* 18 mask 0x00040000 */
265 	LT_DIAG_COND_BROADCAST,		/* 19 mask 0x00080000 */
266 	/* bits 20 - 25 mutex flag group */
267 	LT_DIAG_MUTEX_CREATE,		/* 20 mask 0x00100000 */
268 	LT_DIAG_MUTEX_DESTROY,		/* 21 mask 0x00200000 */
269 	LT_DIAG_MUTEX_LOCK,		/* 22 mask 0x00400000 */
270 	LT_DIAG_MUTEX_TRYLOCK,		/* 23 mask 0x00800000 */
271 	LT_DIAG_MUTEX_BLOCKED,		/* 24 mask 0x01000000 */
272 	LT_DIAG_MUTEX_UNLOCKED,		/* 25 mask 0x02000000 */
273 	/* bits 26 - 27 scheduler flag group - 8 bits */
274 	LT_DIAG_SCHED_CREATE,		/* 26 mask 0x04000000 */
275 	LT_DIAG_SCHED_SHUTDOWN,		/* 27 mask 0x08000000 */
276 	LT_DIAG_EVENT_MAX
277 };
278 
279 #define LT_DIAG_ALL 0xffffffffffffffff
280 
281 
282 /*
283  * Display scheduler stats
284  */
285 void
286 lthread_sched_stats_display(void);
287 
288 /*
289  * return the diagnostic ref val stored in a condition var
290  */
291 uint64_t
292 lthread_cond_diag_ref(struct lthread_cond *c);
293 
294 /*
295  * return the diagnostic ref val stored in a mutex
296  */
297 uint64_t
298 lthread_mutex_diag_ref(struct lthread_mutex *m);
299 
300 #ifdef __cplusplus
301 }
302 #endif
303 
304 #endif				/* LTHREAD_DIAG_API_H_ */
305