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