]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: cache PID & TID in zlog code
authorDavid Lamparter <equinox@diac24.net>
Sun, 11 Apr 2021 01:59:25 +0000 (03:59 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Fri, 18 Jun 2021 19:05:21 +0000 (21:05 +0200)
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 <equinox@diac24.net>
lib/zlog.c
lib/zlog.h

index 91cb7151eb4ce6357e50449bcdf51ef01de0cae5..d44add48b34f4c10b928d001b46fd928e51be045 100644 (file)
@@ -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;
index 1b03e3fd1285edc02aab811af3aff012dfac9aea..7fd7b0e5c7aa8eccbe8d92acf004afe7503a4c2a 100644 (file)
@@ -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.