19#include <sys/syscall.h>
33#ifndef LATREC_TLS_ENTRIES_LOG2
34#define LATREC_TLS_ENTRIES_LOG2 18
36#define LATREC_ENTRIES_LOG2_MIN 12
37#define LATREC_ENTRIES_LOG2_MAX 28
38#define LATREC_MAX_RINGS 64
49static pthread_mutex_t
rings_mu = PTHREAD_MUTEX_INITIALIZER;
68 const char* e = getenv(name);
71 long v = strtol(e, &end, 10);
74 fprintf(stderr,
"[latrec] ignoring %s=%s (expected %d..%d)\n",
90 int n = snprintf(name,
sizeof(name),
"LATREC_ENTRIES_LOG2_%s", role);
91 if (n > 0 && (
size_t)n <
sizeof(name)) {
92 for (
char* c = name +
sizeof(
"LATREC_ENTRIES_LOG2_") - 1; *c; c++)
93 *c = (*c >=
'a' && *c <=
'z') ? (char)(*c -
'a' +
'A')
94 : ((*c >=
'A' && *c <=
'Z') || (*c >=
'0' && *c <=
'9')) ? *c :
'_';
127 if (!role || !*role) {
129 role = program_invocation_short_name;
135 snprintf(name,
sizeof(name),
"%s.%ld", role, (
long)syscall(SYS_gettid));
161 static uint64_t counter;
162 return __atomic_add_fetch(&counter, 1, __ATOMIC_RELAXED);
static pthread_mutex_t rings_mu
static void install_atexit(void)
static void flush_open_rings(void)
latrec_t * latrec_tls_open(void)
void latrec_set_output_dir(const char *dir)
static unsigned entries_log2(const char *role)
static unsigned entries_log2_from(const char *name)
uint64_t latrec_seq_next(void)
latrec_t * latrec_tls_open_as(const char *role)
static latrec_t disabled_ring
#define LATREC_ENTRIES_LOG2_MAX
static pthread_once_t atexit_once
static char output_dir[512]
#define LATREC_TLS_ENTRIES_LOG2
static latrec_t * open_rings[64]
__thread latrec_t * latrec_tls
#define LATREC_ENTRIES_LOG2_MIN
Lock-free per-thread latency stamp recorder (header-only, C99).
static int latrec_open_in(latrec_t *r, const char *dir, const char *name, unsigned entries_log2)
static void latrec_heartbeat(latrec_t *r)