Git fork
at reftables-rust 104 lines 3.2 kB view raw
1#ifndef TR2_CTR_H 2#define TR2_CTR_H 3 4#include "trace2.h" 5#include "trace2/tr2_tgt.h" 6 7/* 8 * Define a mechanism to allow global "counters". 9 * 10 * Counters can be used count interesting activity that does not fit 11 * the "region and data" model, such as code called from many 12 * different regions and/or where you want to count a number of items, 13 * but don't have control of when the last item will be processed, 14 * such as counter the number of calls to `lstat()`. 15 * 16 * Counters differ from Trace2 "data" events. Data events are emitted 17 * immediately and are appropriate for documenting loop counters at 18 * the end of a region, for example. Counter values are accumulated 19 * during the program and final counter values are emitted at program 20 * exit. 21 * 22 * To make this model efficient, we define a compile-time fixed set of 23 * counters and counter ids using a fixed size "counter block" array 24 * in thread-local storage. This gives us constant time, lock-free 25 * access to each counter within each thread. This lets us avoid the 26 * complexities of dynamically allocating a counter and sharing that 27 * definition with other threads. 28 * 29 * Each thread uses the counter block in its thread-local storage to 30 * increment partial sums for each counter (without locking). When a 31 * thread exits, those partial sums are (under lock) added to the 32 * global final sum. 33 * 34 * Partial sums for each counter are optionally emitted when a thread 35 * exits. 36 * 37 * Final sums for each counter are emitted between the "exit" and 38 * "atexit" events. 39 * 40 * A parallel "counter metadata" table contains the "category" and 41 * "name" fields for each counter. This eliminates the need to 42 * include those args in the various counter APIs. 43 */ 44 45/* 46 * The definition of an individual counter as used by an individual 47 * thread (and later in aggregation). 48 */ 49struct tr2_counter { 50 uint64_t value; 51}; 52 53/* 54 * Metadata for a counter. 55 */ 56struct tr2_counter_metadata { 57 const char *category; 58 const char *name; 59 60 /* 61 * True if we should emit per-thread events for this counter 62 * when individual threads exit. 63 */ 64 unsigned int want_per_thread_events:1; 65}; 66 67/* 68 * A compile-time fixed block of counters to insert into thread-local 69 * storage. This wrapper is used to avoid quirks of C and the usual 70 * need to pass an array size argument. 71 */ 72struct tr2_counter_block { 73 struct tr2_counter counter[TRACE2_NUMBER_OF_COUNTERS]; 74}; 75 76/* 77 * Private routines used by trace2.c to increment a counter for the 78 * current thread. 79 */ 80void tr2_counter_increment(enum trace2_counter_id cid, uint64_t value); 81 82/* 83 * Add the current thread's counter data to the global totals. 84 * This is called during thread-exit. 85 * 86 * Caller must be holding the tr2tls_mutex. 87 */ 88void tr2_update_final_counters(void); 89 90/* 91 * Emit per-thread counter data for the current thread. 92 * This is called during thread-exit. 93 */ 94void tr2_emit_per_thread_counters(tr2_tgt_evt_counter_t *fn_apply); 95 96/* 97 * Emit global counter values. 98 * This is called during atexit handling. 99 * 100 * Caller must be holding the tr2tls_mutex. 101 */ 102void tr2_emit_final_counters(tr2_tgt_evt_counter_t *fn_apply); 103 104#endif /* TR2_CTR_H */