ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
callback_timing.c
Go to the documentation of this file.
1
10#include <ascii-chat/log/log.h>
11#include <string.h>
12#include <stdint.h>
13#include <limits.h>
14#include <ascii-chat/atomic.h>
15
20
22 if (!stats) {
23 return;
24 }
25
26 uint64_t duration_ns = (end_ns > start_ns) ? (end_ns - start_ns) : 0;
27 uint64_t count = atomic_fetch_add_u64(&stats->count, 1);
28
29 // Track cumulative duration
30 atomic_fetch_add_u64(&stats->total_duration_ns, duration_ns);
31
32 // Update last timestamp (atomically swap)
33 uint64_t prev_last_ns = atomic_load_u64(&stats->last_ns);
34 while (!atomic_cas_u64(&stats->last_ns, &prev_last_ns, end_ns)) {
35 // Retry if CAS failed due to concurrent update
36 }
37
38 // Calculate interval from previous callback (if not the first one)
39 if (count > 0 && prev_last_ns > 0) {
40 uint64_t interval_ns = (end_ns > prev_last_ns) ? (end_ns - prev_last_ns) : 0;
41
42 // Track min intervals (atomic compare-and-swap loop to avoid TOCTOU race)
43 if (interval_ns > 0) {
44 uint64_t current_min = atomic_load_u64(&stats->min_interval_ns);
45 while (interval_ns < current_min) {
46 if (atomic_cas_u64(&stats->min_interval_ns, &current_min, interval_ns)) {
47 break;
48 }
49 // CAS failed - reload current value and retry if still applicable
50 current_min = atomic_load_u64(&stats->min_interval_ns);
51 }
52 }
53
54 // Track max intervals (atomic compare-and-swap loop to avoid TOCTOU race)
55 uint64_t current_max = atomic_load_u64(&stats->max_interval_ns);
56 while (interval_ns > current_max) {
57 if (atomic_cas_u64(&stats->max_interval_ns, &current_max, interval_ns)) {
58 break;
59 }
60 // CAS failed - reload current value and retry if still applicable
61 current_max = atomic_load_u64(&stats->max_interval_ns);
62 }
63 }
64}
65
71
72 log_info("\n===== WEBSOCKET CALLBACK TIMING STATISTICS =====");
73 log_info("Timestamp: %lu ns", websocket_callback_timing_start());
74
75 // PROTOCOL_INIT stats
76 log_info("LWS_CALLBACK_PROTOCOL_INIT:");
77 log_info(" Total invocations: %lu", protocol_init_count);
78 if (protocol_init_count > 0) {
80 uint64_t avg_duration = total_duration / protocol_init_count;
81 log_info(" Avg duration: %lu ns", avg_duration);
82 }
83
84 // PROTOCOL_DESTROY stats
85 log_info("LWS_CALLBACK_PROTOCOL_DESTROY:");
86 log_info(" Total invocations: %lu", protocol_destroy_count);
87 if (protocol_destroy_count > 0) {
89 uint64_t avg_duration = total_duration / protocol_destroy_count;
90 log_info(" Avg duration: %lu ns", avg_duration);
91 }
92
93 // SERVER_WRITEABLE stats
94 log_info("LWS_CALLBACK_SERVER_WRITEABLE:");
95 log_info(" Total invocations: %lu", writeable_count);
96 if (writeable_count > 0) {
98 uint64_t avg_duration = total_duration / writeable_count;
101 log_info(" Avg duration: %lu ns", avg_duration);
102 if (min_interval != UINT64_MAX) {
103 log_info(" Min interval between callbacks: %lu ns (%.2f Hz)", min_interval, 1e9 / (double)min_interval);
104 }
105 if (max_interval > 0) {
106 log_info(" Max interval between callbacks: %lu ns (%.2f Hz)", max_interval, 1e9 / (double)max_interval);
107 }
108 }
109
110 // RECEIVE stats
111 log_info("LWS_CALLBACK_RECEIVE:");
112 log_info(" Total invocations: %lu", receive_count);
113 if (receive_count > 0) {
115 uint64_t avg_duration = total_duration / receive_count;
118 log_info(" Avg duration: %lu ns", avg_duration);
119 if (min_interval != UINT64_MAX) {
120 log_info(" Min interval between callbacks: %lu ns (%.2f Hz)", min_interval, 1e9 / (double)min_interval);
121 }
122 if (max_interval > 0) {
123 log_info(" Max interval between callbacks: %lu ns (%.2f Hz)", max_interval, 1e9 / (double)max_interval);
124 }
125 }
126
127 log_info("===== END TIMING STATISTICS =====\n");
128}
129
asciichat_error_stats_t stats
uint64_t atomic_fetch_add_u64(atomic_t *a, uint64_t delta)
Atomically add to a uint64_t and return the previous value.
Definition atomic.c:248
bool atomic_cas_u64(atomic_t *a, uint64_t *expected, uint64_t new_value)
Atomically compare-and-swap a uint64_t.
Definition atomic.c:264
void atomic_store_u64(atomic_t *a, uint64_t value)
Atomically store a uint64_t value.
Definition atomic.c:241
uint64_t atomic_load_u64(atomic_t *a)
Atomically load a uint64_t value.
Definition atomic.c:233
⚛️ Atomic operations abstraction layer with debug tracking
void websocket_callback_timing_reset(void)
Reset timing statistics.
websocket_callback_timing_t g_ws_callback_timing
Global timing tracker - shared across all WebSocket connections.
void websocket_callback_timing_record(websocket_callback_stats_t *stats, uint64_t start_ns, uint64_t end_ns)
Record callback invocation.
void websocket_callback_timing_log_stats(void)
Log current callback statistics.
WebSocket callback timing instrumentation.
unsigned long long uint64_t
Definition common.h:59
#define log_info(...)
Log an INFO message.
Definition log/log.h:561
Application limits and constraints.
📝 Logging API with multiple log levels and terminal output control
Per-callback timing statistics.
WebSocket callback timing data for protocol lifecycle.
websocket_callback_stats_t receive
websocket_callback_stats_t protocol_destroy
websocket_callback_stats_t server_writeable
websocket_callback_stats_t protocol_init