From 78598fd0195510d0d1338bf8c28e606d67e63359 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 11 Apr 2021 03:59:25 +0200 Subject: [PATCH] lib: cache PID & TID in zlog code glibc removed its pid cache a while back, and grabbing this from TLS is faster than repeatedly calling the kernel... Also use `intmax_t` which is more appropriate for both PID & TID. Signed-off-by: David Lamparter --- lib/zlog.c | 35 ++++++++++++++++++++++++++++++++--- lib/zlog.h | 5 +++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lib/zlog.c b/lib/zlog.c index 91cb7151eb..d44add48b3 100644 --- a/lib/zlog.c +++ b/lib/zlog.c @@ -220,8 +220,15 @@ static inline void zlog_tls_set(struct zlog_tls *val) #endif #ifdef CAN_DO_TLS -static long zlog_gettid(void) +static intmax_t zlog_gettid(void) { +#ifndef __OpenBSD__ + /* accessing a TLS variable is much faster than a syscall */ + static thread_local intmax_t cached_tid = -1; + if (cached_tid != -1) + return cached_tid; +#endif + long rv = -1; #ifdef HAVE_PTHREAD_GETTHREADID_NP rv = pthread_getthreadid_np(); @@ -241,6 +248,10 @@ static long zlog_gettid(void) rv = mach_thread_self(); mach_port_deallocate(mach_task_self(), rv); #endif + +#ifndef __OpenBSD__ + cached_tid = rv; +#endif return rv; } @@ -260,7 +271,7 @@ void zlog_tls_buffer_init(void) for (i = 0; i < array_size(zlog_tls->msgp); i++) zlog_tls->msgp[i] = &zlog_tls->msgs[i]; - snprintfrr(mmpath, sizeof(mmpath), "logbuf.%ld", zlog_gettid()); + snprintfrr(mmpath, sizeof(mmpath), "logbuf.%jd", zlog_gettid()); mmfd = openat(zlog_tmpdirfd, mmpath, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0600); @@ -327,7 +338,7 @@ void zlog_tls_buffer_fini(void) zlog_tls_free(zlog_tls); zlog_tls_set(NULL); - snprintfrr(mmpath, sizeof(mmpath), "logbuf.%ld", zlog_gettid()); + snprintfrr(mmpath, sizeof(mmpath), "logbuf.%jd", zlog_gettid()); if (do_unlink && unlinkat(zlog_tmpdirfd, mmpath, 0)) zlog_err("unlink logbuf: %s (%d)", strerror(errno), errno); } @@ -342,6 +353,24 @@ void zlog_tls_buffer_fini(void) } #endif +void zlog_msg_pid(struct zlog_msg *msg, intmax_t *pid, intmax_t *tid) +{ +#ifndef __OpenBSD__ + static thread_local intmax_t cached_pid = -1; + if (cached_pid != -1) + *pid = cached_pid; + else + cached_pid = *pid = (intmax_t)getpid(); +#else + *pid = (intmax_t)getpid(); +#endif +#ifdef CAN_DO_TLS + *tid = zlog_gettid(); +#else + *tid = *pid; +#endif +} + static inline void zlog_tls_free(void *arg) { struct zlog_tls *zlog_tls = arg; diff --git a/lib/zlog.h b/lib/zlog.h index 1b03e3fd12..7fd7b0e5c7 100644 --- a/lib/zlog.h +++ b/lib/zlog.h @@ -178,6 +178,11 @@ extern size_t zlog_msg_ts(struct zlog_msg *msg, struct fbuf *out, extern size_t zlog_msg_ts_3164(struct zlog_msg *msg, struct fbuf *out, uint32_t flags); +/* currently just returns the current PID/TID since we never write another + * thread's messages + */ +extern void zlog_msg_pid(struct zlog_msg *msg, intmax_t *pid, intmax_t *tid); + /* This list & struct implements the actual logging targets. It is accessed * lock-free from all threads, and thus MUST only be changed atomically, i.e. * RCU. -- 2.39.5