]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add `%pTH` / `%pTHD` for printing thread info
authorDavid Lamparter <equinox@opensourcerouting.org>
Wed, 12 Jan 2022 01:07:41 +0000 (02:07 +0100)
committerDavid Lamparter <equinox@opensourcerouting.org>
Fri, 14 Jan 2022 12:33:57 +0000 (13:33 +0100)
Refer to docs in doc/developer for details.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
doc/developer/logging.rst
lib/thread.c
lib/thread.h

index 5aca27d7f732be864d306694b1b387b50014e24f..4e6fc04206e0d78c8f8415d947ed0836df07eb29 100644 (file)
@@ -335,6 +335,28 @@ Time/interval formats
    ``mx``: :frrfmtout:`09:09`, :frrfmtout:`--:--` - this replaces
    :c:func:`pim_time_timer_to_mmss()`.
 
+FRR library helper formats
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. frrfmt:: %pTH (struct thread *)
+
+   Print remaining time on timer thread. Interval-printing flag characters
+   listed above for ``%pTV`` can be added, e.g. ``%pTHtx``.
+
+   ``NULL`` pointers are printed as ``-``.
+
+.. frrfmt:: %pTHD (struct thread *)
+
+   Print debugging information for given thread.  Sample output:
+
+   .. code-block:: none
+
+      {(thread *)NULL}
+      {(thread *)0x55a3b5818910 arg=0x55a3b5827c50 timer  r=7.824      mld_t_query() &mld_ifp->t_query from pimd/pim6_mld.c:1369}
+      {(thread *)0x55a3b5827230 arg=0x55a3b5827c50 read   fd=16        mld_t_recv() &mld_ifp->t_recv from pimd/pim6_mld.c:1186}
+
+   (The output is aligned to some degree.)
+
 General utility formats
 ^^^^^^^^^^^^^^^^^^^^^^^
 
index 7b223ed6de84f293b51f639a0d9fb52ac7af84c4..baa987a829c3daaa93bcd1867afc5572ac40a596 100644 (file)
@@ -2056,3 +2056,70 @@ bool thread_is_scheduled(struct thread *thread)
 
        return true;
 }
+
+static ssize_t printfrr_thread_dbg(struct fbuf *buf, struct printfrr_eargs *ea,
+                                  const struct thread *thread)
+{
+       static const char * const types[] = {
+               [THREAD_READ] = "read",
+               [THREAD_WRITE] = "write",
+               [THREAD_TIMER] = "timer",
+               [THREAD_EVENT] = "event",
+               [THREAD_READY] = "ready",
+               [THREAD_UNUSED] = "unused",
+               [THREAD_EXECUTE] = "exec",
+       };
+       ssize_t rv = 0;
+       char info[16] = "";
+
+       if (!thread)
+               return bputs(buf, "{(thread *)NULL}");
+
+       rv += bprintfrr(buf, "{(thread *)%p arg=%p", thread, thread->arg);
+
+       if (thread->type < array_size(types) && types[thread->type])
+               rv += bprintfrr(buf, " %-6s", types[thread->type]);
+       else
+               rv += bprintfrr(buf, " INVALID(%u)", thread->type);
+
+       switch (thread->type) {
+       case THREAD_READ:
+       case THREAD_WRITE:
+               snprintfrr(info, sizeof(info), "fd=%d", thread->u.fd);
+               break;
+
+       case THREAD_TIMER:
+               snprintfrr(info, sizeof(info), "r=%pTVMud", &thread->u.sands);
+               break;
+       }
+
+       rv += bprintfrr(buf, " %-12s %s() %s from %s:%d}", info,
+                       thread->xref->funcname, thread->xref->dest,
+                       thread->xref->xref.file, thread->xref->xref.line);
+       return rv;
+}
+
+printfrr_ext_autoreg_p("TH", printfrr_thread)
+static ssize_t printfrr_thread(struct fbuf *buf, struct printfrr_eargs *ea,
+                              const void *ptr)
+{
+       const struct thread *thread = ptr;
+       struct timespec remain = {};
+
+       if (ea->fmt[0] == 'D') {
+               ea->fmt++;
+               return printfrr_thread_dbg(buf, ea, thread);
+       }
+
+       if (!thread) {
+               /* need to jump over time formatting flag characters in the
+                * input format string, i.e. adjust ea->fmt!
+                */
+               printfrr_time(buf, ea, &remain,
+                             TIMEFMT_TIMER_DEADLINE | TIMEFMT_SKIP);
+               return bputch(buf, '-');
+       }
+
+       TIMEVAL_TO_TIMESPEC(&thread->u.sands, &remain);
+       return printfrr_time(buf, ea, &remain, TIMEFMT_TIMER_DEADLINE);
+}
index 39f21da11d332c0fc318acc6de89f1397902eca7..49a70696d0d8ad8a27787783f8e117b36bade322 100644 (file)
@@ -128,6 +128,10 @@ struct thread {
        pthread_mutex_t mtx;   /* mutex for thread.c functions */
 };
 
+#ifdef _FRR_ATTRIBUTE_PRINTFRR
+#pragma FRR printfrr_ext "%pTH" (struct thread *)
+#endif
+
 struct cpu_thread_history {
        int (*func)(struct thread *);
        atomic_size_t total_cpu_warn;