10#include "../asciichat_errno.h"
11#include "../platform/rwlock.h"
12#include "../platform/abstraction.h"
40 if (g_timer_manager.initialized) {
53 g_timer_manager.timers = NULL;
54 g_timer_manager.initialized =
true;
61 if (!g_timer_manager.initialized) {
69 HASH_ITER(hh, g_timer_manager.timers, current, tmp) {
70 HASH_DEL(g_timer_manager.timers, current);
75 g_timer_manager.timers = NULL;
76 g_timer_manager.initialized =
false;
85 if (!g_timer_manager.initialized) {
99 HASH_FIND_STR(g_timer_manager.timers, name, existing);
116 size_t name_len = strlen(name) + 1;
129 HASH_ADD_KEYPTR(hh, g_timer_manager.timers, timer->
name, strlen(timer->
name), timer);
136 if (!g_timer_manager.initialized) {
150 HASH_FIND_STR(g_timer_manager.timers, name, timer);
154 log_warn(
"Timer '%s' not found", name);
161 double elapsed_ns = stm_ns(elapsed_ticks);
164 char duration_str[32];
168 log_debug(
"Timer '%s': %s", name, duration_str);
171 HASH_DEL(g_timer_manager.timers, timer);
180 return g_timer_manager.initialized;
188 if (!buffer || buffer_size == 0) {
193 if (nanoseconds < 0) {
194 nanoseconds = -nanoseconds;
201 written = snprintf(buffer, buffer_size,
"%.0fns", nanoseconds);
207 written = snprintf(buffer, buffer_size,
"%.1fµs", us);
209 written = snprintf(buffer, buffer_size,
"%.0fµs", us);
216 written = snprintf(buffer, buffer_size,
"%.1fms", ms);
218 written = snprintf(buffer, buffer_size,
"%.0fms", ms);
225 written = snprintf(buffer, buffer_size,
"%.2fs", s);
227 written = snprintf(buffer, buffer_size,
"%.1fs", s);
232 int minutes = (int)(nanoseconds /
NS_PER_MIN);
234 written = snprintf(buffer, buffer_size,
"%dm%ds", minutes, seconds);
239 double remaining_ns = nanoseconds - ((double)hours *
NS_PER_HOUR);
240 int minutes = (int)(remaining_ns /
NS_PER_MIN);
241 double remaining_after_min = remaining_ns - ((double)minutes *
NS_PER_MIN);
242 int seconds = (int)(remaining_after_min /
NS_PER_SEC);
243 written = snprintf(buffer, buffer_size,
"%dh%dm%ds", hours, minutes, seconds);
248 double remaining_ns = nanoseconds - ((double)days *
NS_PER_DAY);
250 remaining_ns = remaining_ns - ((double)hours *
NS_PER_HOUR);
251 int minutes = (int)(remaining_ns /
NS_PER_MIN);
252 double remaining_after_min = remaining_ns - ((double)minutes *
NS_PER_MIN);
253 int seconds = (int)(remaining_after_min /
NS_PER_SEC);
254 written = snprintf(buffer, buffer_size,
"%dd%dh%dm%ds", days, hours, minutes, seconds);
259 written = snprintf(buffer, buffer_size,
"%.1fy", years);
262 if (written < 0 || (
size_t)written >= buffer_size) {
271 double nanoseconds = milliseconds *
NS_PER_MS;
286 if (!state || !config) {
308 double desired_multiplier;
310 if (queue_depth > target_depth) {
313 size_t backlog = queue_depth - target_depth;
318 double backlog_factor = 1.0 + ((double)backlog / (
double)(target_depth + 1));
362 uint64_t sleep_us = sleep_ns / 1000;
#define SAFE_STRNCPY(dst, src, size)
#define SAFE_MALLOC(size, cast)
unsigned long long uint64_t
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
#define log_warn(...)
Log a WARN message.
#define log_debug(...)
Log a DEBUG message.
double timer_stop(const char *name)
Stop a named timer and return elapsed time.
void timer_system_cleanup(void)
Cleanup the timing system.
bool timer_start(const char *name)
Start a named timer.
int format_duration_ns(double nanoseconds, char *buffer, size_t buffer_size)
Format nanoseconds as human-readable duration string.
uint64_t adaptive_sleep_calculate(adaptive_sleep_state_t *state, size_t queue_depth, size_t target_depth)
Calculate adaptive sleep time based on queue depth.
int format_duration_s(double seconds, char *buffer, size_t buffer_size)
Format seconds as human-readable duration string.
void adaptive_sleep_init(adaptive_sleep_state_t *state, const adaptive_sleep_config_t *config)
Initialize adaptive sleep state with configuration.
int format_duration_ms(double milliseconds, char *buffer, size_t buffer_size)
Format milliseconds as human-readable duration string.
bool timer_is_initialized(void)
Check if timing system is initialized.
bool timer_system_init(void)
Initialize the timing system.
void adaptive_sleep_do(adaptive_sleep_state_t *state, size_t queue_depth, size_t target_depth)
Calculate sleep time and immediately sleep for that duration.
🔢 Mathematical Utility Functions
Configuration for adaptive sleep behavior.
double min_speed_multiplier
Minimum speed (max sleep) - usually 1.0 (baseline speed)
double max_speed_multiplier
Maximum speed (min sleep) - e.g., 4.0 = process 4x faster.
uint64_t baseline_sleep_ns
Normal sleep time in nanoseconds (when queue is at target)
double speedup_rate
Ramp-up rate when queue builds (0.0-1.0, higher = faster ramp)
double slowdown_rate
Ramp-down rate when queue empties (0.0-1.0, higher = faster ramp)
Runtime state for adaptive sleep.
double current_speed_multiplier
Current speed state (1.0 = baseline, >1.0 = faster)
uint64_t last_sleep_ns
Last calculated sleep time (for debugging)
adaptive_sleep_config_t config
Configuration (copied, not referenced)
Individual timer record for a named timing operation.
uint64_t start_ticks
Start time in sokol ticks.
char * name
Timer name (heap-allocated, unique key)
rwlock_t rwlock
Read-write lock for thread-safe access (uthash requires external locking)
timer_record_t * timers
Hash table of active timers (uthash head pointer)
bool initialized
Initialization state.
⏱️ High-precision timing utilities using sokol_time.h and uthash
#️⃣ Wrapper for uthash.h that ensures common.h is included first
🔤 String Manipulation and Shell Escaping Utilities