]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Displaced show threads command to its own file
authorMaria Matejka <mq@ucw.cz>
Thu, 29 Aug 2024 08:10:37 +0000 (10:10 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 23 Feb 2025 17:28:44 +0000 (18:28 +0100)
lib/io-loop.h
lib/timer.h
sysdep/unix/Makefile
sysdep/unix/io-cli.c [new file with mode: 0644]
sysdep/unix/io-loop.c
sysdep/unix/io-loop.h

index 9f08420a60227bb4e545eeebe18ffd776a4616b3..1923af4e67838688db474a49037fe0df6a82a9ad 100644 (file)
@@ -7,15 +7,17 @@
 #ifndef _BIRD_IO_LOOP_H_
 #define _BIRD_IO_LOOP_H_
 
+extern struct birdloop main_birdloop;
+
 #include "nest/bird.h"
 #include "lib/lists.h"
 #include "lib/locking.h"
 #include "lib/resource.h"
+#include "lib/buffer.h"
 #include "lib/event.h"
+#include "lib/timer.h"
 #include "lib/socket.h"
 
-extern struct birdloop main_birdloop;
-
 /* Currently running birdloop */
 extern _Thread_local struct birdloop *this_birdloop;
 
index 84a6bac5dddff3eb4d78a3d6f5f1746955e77801..91015622bfcba4555f39f320345b83728b034249 100644 (file)
@@ -120,6 +120,10 @@ void timers_fire(struct timeloop *loop);
 /* For extra fine precision */
 u64 ns_now(void);
 
+#define NSEC_IN_SEC    ((u64) (1000 * 1000 * 1000))
+#define NSEC_TO_SEC(x) ((x) / NSEC_IN_SEC)
+#define CURRENT_SEC    NSEC_TO_SEC(ns_now())
+
 struct timeformat {
   const char *fmt1, *fmt2;
   btime limit;
index dba12877256d43814248998f3d06950a2b1d60cc..574d19bdfd95ee3a372906ffa128c7e19327eaeb 100644 (file)
@@ -1,4 +1,4 @@
-src := alloc.c io.c io-loop.c krt.c log.c main.c random.c domain.c socket.c file.c time.c
+src := alloc.c io.c io-cli.c io-loop.c krt.c log.c main.c random.c domain.c socket.c file.c time.c
 obj := $(src-o-files)
 $(all-daemon)
 $(cf-local)
diff --git a/sysdep/unix/io-cli.c b/sysdep/unix/io-cli.c
new file mode 100644 (file)
index 0000000..7188a52
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *     CLI: Show threads
+ */
+
+#include "nest/bird.h"
+
+#include "lib/io-loop.h"
+#include "sysdep/unix/io-loop.h"
+#include "nest/cli.h"
+#include "conf/conf.h"
+
+
+struct bird_thread_show_data {
+  struct bird_thread_syncer sync;
+  cli *cli;
+  linpool *lp;
+  u8 show_loops;
+  uint line_pos;
+  uint line_max;
+  const char **lines;
+};
+
+#define tsd_append(...)                do { \
+  if (!tsd->lines) \
+    tsd->lines = mb_allocz(tsd->sync.pool, sizeof(const char *) * tsd->line_max); \
+  if (tsd->line_pos >= tsd->line_max) \
+    tsd->lines = mb_realloc(tsd->lines, sizeof (const char *) * (tsd->line_max *= 2)); \
+  tsd->lines[tsd->line_pos++] = lp_sprintf(tsd->lp, __VA_ARGS__); \
+} while (0)
+
+static void
+bird_thread_show_cli_cont(struct cli *c UNUSED)
+{
+  /* Explicitly do nothing to prevent CLI from trying to parse another command. */
+}
+
+static bool
+bird_thread_show_cli_cleanup(struct cli *c UNUSED)
+{
+  /* Defer the cleanup until the writeout is finished. */
+  return false;
+}
+
+static void
+bird_thread_show_spent_time(struct bird_thread_show_data *tsd, const char *name, struct spent_time *st)
+{
+  char b[TIME_BY_SEC_SIZE * sizeof("1234567890, ")], *bptr = b, *bend = b + sizeof(b);
+  uint cs = CURRENT_SEC;
+  uint fs = NSEC_TO_SEC(st->last_written_ns);
+
+  for (uint i = 0; i <= cs && i < TIME_BY_SEC_SIZE; i++)
+    bptr += bsnprintf(bptr, bend - bptr, "% 10lu ",
+       (cs - i > fs) ? 0 : st->by_sec_ns[(cs - i) % TIME_BY_SEC_SIZE]);
+  bptr[-1] = 0; /* Drop the trailing space */
+
+  tsd_append("    %s total time: % 9t s; last %d secs [ns]: %s", name, st->total_ns NS, MIN(CURRENT_SEC+1, TIME_BY_SEC_SIZE), b);
+}
+
+static void
+bird_thread_show_loop(struct bird_thread_show_data *tsd, struct birdloop *loop)
+{
+  tsd_append("  Loop %s", domain_name(loop->time.domain));
+  bird_thread_show_spent_time(tsd, "Working ", &loop->working);
+  bird_thread_show_spent_time(tsd, "Locking ", &loop->locking);
+}
+
+static void
+bird_thread_show(struct bird_thread_syncer *sync)
+{
+  SKIP_BACK_DECLARE(struct bird_thread_show_data, tsd, sync, sync);
+
+  if (!tsd->lp)
+    tsd->lp = lp_new(tsd->sync.pool);
+
+  if (tsd->show_loops)
+    tsd_append("Thread %04x %s (busy counter %d)", THIS_THREAD_ID, this_thread->busy_active ? " [busy]" : "", this_thread->busy_counter);
+
+  u64 total_time_ns = 0;
+  struct birdloop *loop;
+  WALK_LIST(loop, this_thread->loops)
+  {
+    if (tsd->show_loops)
+      bird_thread_show_loop(tsd, loop);
+
+    total_time_ns += loop->working.total_ns + loop->locking.total_ns;
+  }
+
+  if (tsd->show_loops)
+  {
+    tsd_append("  Total working time: %t", total_time_ns NS);
+    bird_thread_show_spent_time(tsd, "Overhead", &this_thread->overhead);
+    bird_thread_show_spent_time(tsd, "Idle    ", &this_thread->idle);
+  }
+  else
+    tsd_append("%04x%s     % 9.3t s   % 9.3t s   % 9.3t s",
+       THIS_THREAD_ID, this_thread->busy_active ? " [busy]" : "       ",
+       total_time_ns NS, this_thread->overhead.total_ns NS,
+       (ns_now() - this_thread->meta->last_transition_ns) NS);
+}
+
+static void
+cmd_show_threads_done(struct bird_thread_syncer *sync)
+{
+  SKIP_BACK_DECLARE(struct bird_thread_show_data, tsd, sync, sync);
+  ASSERT_DIE(birdloop_inside(&main_birdloop));
+
+  /* The client lost their patience and dropped the session early. */
+  if (!tsd->cli->sock)
+  {
+    mb_free(tsd);
+    rp_free(tsd->cli->pool);
+    return;
+  }
+
+  tsd->cli->cont = NULL;
+  tsd->cli->cleanup = NULL;
+
+  for (int i=0; i<2; i++)
+  {
+    struct birdloop_pickup_group *group = &pickup_groups[i];
+
+    LOCK_DOMAIN(attrs, group->domain);
+    uint count = 0;
+    u64 total_time_ns = 0;
+    if (!EMPTY_LIST(group->loops))
+    {
+      if (tsd->show_loops)
+       tsd_append("Unassigned loops in group %d:", i);
+
+      struct birdloop *loop;
+      WALK_LIST(loop, group->loops)
+      {
+       if (tsd->show_loops)
+         bird_thread_show_loop(tsd, loop);
+
+       total_time_ns += loop->working.total_ns + loop->locking.total_ns;
+       count++;
+      }
+
+      if (tsd->show_loops)
+       tsd_append("  Total working time: %t", total_time_ns NS);
+      else
+       tsd_append("Unassigned %d loops in group %d, total time %t", count, i, total_time_ns NS);
+    }
+    else
+      tsd_append("All loops in group %d are assigned.", i);
+
+    UNLOCK_DOMAIN(attrs, group->domain);
+  }
+
+  if (!tsd->show_loops)
+    cli_printf(tsd->cli, -1027, "Thread ID       Working         Overhead        Last Pickup/Drop");
+
+  for (uint i = 0; i < tsd->line_pos - 1; i++)
+    cli_printf(tsd->cli, -1027, "%s", tsd->lines[i]);
+
+  cli_printf(tsd->cli, 1027, "%s", tsd->lines[tsd->line_pos-1]);
+  cli_write_trigger(tsd->cli);
+  mb_free(tsd);
+}
+
+void
+cmd_show_threads(int show_loops)
+{
+  struct bird_thread_show_data *tsd = mb_allocz(&root_pool, sizeof(struct bird_thread_show_data));
+  tsd->cli = this_cli;
+  tsd->show_loops = show_loops;
+  tsd->line_pos = 0;
+  tsd->line_max = 64;
+
+  this_cli->cont = bird_thread_show_cli_cont;
+  this_cli->cleanup = bird_thread_show_cli_cleanup;
+
+  bird_thread_sync_all(&tsd->sync, bird_thread_show, cmd_show_threads_done, "Show Threads");
+}
index a45813940ee7139df76582d11d9dbfc8b00137b0..438373a70541e6ef2a6817a6d51634bdbcb25c33 100644 (file)
@@ -28,7 +28,6 @@
 #include "lib/io-loop.h"
 #include "sysdep/unix/io-loop.h"
 #include "conf/conf.h"
-#include "nest/cli.h"
 
 #define THREAD_STACK_SIZE      65536   /* To be lowered in near future */
 
@@ -54,8 +53,6 @@ static void ns_init(void)
     bug("clock_gettime: %m");
 }
 
-#define NSEC_IN_SEC    ((u64) (1000 * 1000 * 1000))
-
 u64 ns_now(void)
 {
   struct timespec ts;
@@ -65,9 +62,6 @@ u64 ns_now(void)
   return (u64) (ts.tv_sec - ns_begin.tv_sec) * NSEC_IN_SEC + ts.tv_nsec - ns_begin.tv_nsec;
 }
 
-#define NSEC_TO_SEC(x) ((x) / NSEC_IN_SEC)
-#define CURRENT_SEC    NSEC_TO_SEC(ns_now())
-
 static _Thread_local struct spent_time *account_target_spent_time;
 static _Thread_local u64 *account_target_total;
 static _Thread_local u64 account_last;
@@ -571,17 +565,7 @@ sockets_fire(struct birdloop *loop, bool read, bool write)
 static void bird_thread_start_event(void *_data);
 static void bird_thread_busy_set(struct bird_thread *thr, int val);
 
-struct birdloop_pickup_group {
-  DOMAIN(attrs) domain;
-  list loops;
-  list threads;
-  uint thread_count;
-  uint thread_busy_count;
-  uint loop_count;
-  uint loop_unassigned_count;
-  btime max_latency;
-  event start_threads;
-} pickup_groups[2] = {
+struct birdloop_pickup_group pickup_groups[2] = {
   {
     /* all zeroes */
   },
@@ -593,7 +577,7 @@ struct birdloop_pickup_group {
   },
 };
 
-static _Thread_local struct bird_thread *this_thread;
+_Thread_local struct bird_thread *this_thread;
 
 static void
 birdloop_set_thread(struct birdloop *loop, struct bird_thread *thr, struct birdloop_pickup_group *group)
@@ -1235,170 +1219,6 @@ bird_thread_sync_all(struct bird_thread_syncer *sync,
 }
 
 
-struct bird_thread_show_data {
-  struct bird_thread_syncer sync;
-  cli *cli;
-  linpool *lp;
-  u8 show_loops;
-  uint line_pos;
-  uint line_max;
-  const char **lines;
-};
-
-#define tsd_append(...)                do { \
-  if (!tsd->lines) \
-    tsd->lines = mb_allocz(tsd->sync.pool, sizeof(const char *) * tsd->line_max); \
-  if (tsd->line_pos >= tsd->line_max) \
-    tsd->lines = mb_realloc(tsd->lines, sizeof (const char *) * (tsd->line_max *= 2)); \
-  tsd->lines[tsd->line_pos++] = lp_sprintf(tsd->lp, __VA_ARGS__); \
-} while (0)
-
-static void
-bird_thread_show_cli_cont(struct cli *c UNUSED)
-{
-  /* Explicitly do nothing to prevent CLI from trying to parse another command. */
-}
-
-static bool
-bird_thread_show_cli_cleanup(struct cli *c UNUSED)
-{
-  /* Defer the cleanup until the writeout is finished. */
-  return false;
-}
-
-static void
-bird_thread_show_spent_time(struct bird_thread_show_data *tsd, const char *name, struct spent_time *st)
-{
-  char b[TIME_BY_SEC_SIZE * sizeof("1234567890, ")], *bptr = b, *bend = b + sizeof(b);
-  uint cs = CURRENT_SEC;
-  uint fs = NSEC_TO_SEC(st->last_written_ns);
-
-  for (uint i = 0; i <= cs && i < TIME_BY_SEC_SIZE; i++)
-    bptr += bsnprintf(bptr, bend - bptr, "% 10lu ",
-       (cs - i > fs) ? 0 : st->by_sec_ns[(cs - i) % TIME_BY_SEC_SIZE]);
-  bptr[-1] = 0; /* Drop the trailing space */
-
-  tsd_append("    %s total time: % 9t s; last %d secs [ns]: %s", name, st->total_ns NS, MIN(CURRENT_SEC+1, TIME_BY_SEC_SIZE), b);
-}
-
-static void
-bird_thread_show_loop(struct bird_thread_show_data *tsd, struct birdloop *loop)
-{
-  tsd_append("  Loop %s", domain_name(loop->time.domain));
-  bird_thread_show_spent_time(tsd, "Working ", &loop->working);
-  bird_thread_show_spent_time(tsd, "Locking ", &loop->locking);
-}
-
-static void
-bird_thread_show(struct bird_thread_syncer *sync)
-{
-  SKIP_BACK_DECLARE(struct bird_thread_show_data, tsd, sync, sync);
-
-  if (!tsd->lp)
-    tsd->lp = lp_new(tsd->sync.pool);
-
-  if (tsd->show_loops)
-    tsd_append("Thread %04x %s (busy counter %d)", THIS_THREAD_ID, this_thread->busy_active ? " [busy]" : "", this_thread->busy_counter);
-
-  u64 total_time_ns = 0;
-  struct birdloop *loop;
-  WALK_LIST(loop, this_thread->loops)
-  {
-    if (tsd->show_loops)
-      bird_thread_show_loop(tsd, loop);
-
-    total_time_ns += loop->working.total_ns + loop->locking.total_ns;
-  }
-
-  if (tsd->show_loops)
-  {
-    tsd_append("  Total working time: %t", total_time_ns NS);
-    bird_thread_show_spent_time(tsd, "Overhead", &this_thread->overhead);
-    bird_thread_show_spent_time(tsd, "Idle    ", &this_thread->idle);
-  }
-  else
-    tsd_append("%04x%s     % 9.3t s   % 9.3t s   % 9.3t s",
-       THIS_THREAD_ID, this_thread->busy_active ? " [busy]" : "       ",
-       total_time_ns NS, this_thread->overhead.total_ns NS,
-       (ns_now() - this_thread->meta->last_transition_ns) NS);
-}
-
-static void
-cmd_show_threads_done(struct bird_thread_syncer *sync)
-{
-  SKIP_BACK_DECLARE(struct bird_thread_show_data, tsd, sync, sync);
-  ASSERT_DIE(birdloop_inside(&main_birdloop));
-
-  /* The client lost their patience and dropped the session early. */
-  if (!tsd->cli->sock)
-  {
-    mb_free(tsd);
-    rp_free(tsd->cli->pool);
-    return;
-  }
-
-  tsd->cli->cont = NULL;
-  tsd->cli->cleanup = NULL;
-
-  for (int i=0; i<2; i++)
-  {
-    struct birdloop_pickup_group *group = &pickup_groups[i];
-
-    LOCK_DOMAIN(attrs, group->domain);
-    uint count = 0;
-    u64 total_time_ns = 0;
-    if (!EMPTY_LIST(group->loops))
-    {
-      if (tsd->show_loops)
-       tsd_append("Unassigned loops in group %d:", i);
-
-      struct birdloop *loop;
-      WALK_LIST(loop, group->loops)
-      {
-       if (tsd->show_loops)
-         bird_thread_show_loop(tsd, loop);
-
-       total_time_ns += loop->working.total_ns + loop->locking.total_ns;
-       count++;
-      }
-
-      if (tsd->show_loops)
-       tsd_append("  Total working time: %t", total_time_ns NS);
-      else
-       tsd_append("Unassigned %d loops in group %d, total time %t", count, i, total_time_ns NS);
-    }
-    else
-      tsd_append("All loops in group %d are assigned.", i);
-
-    UNLOCK_DOMAIN(attrs, group->domain);
-  }
-
-  if (!tsd->show_loops)
-    cli_printf(tsd->cli, -1027, "Thread ID       Working         Overhead        Last Pickup/Drop");
-
-  for (uint i = 0; i < tsd->line_pos - 1; i++)
-    cli_printf(tsd->cli, -1027, "%s", tsd->lines[i]);
-
-  cli_printf(tsd->cli, 1027, "%s", tsd->lines[tsd->line_pos-1]);
-  cli_write_trigger(tsd->cli);
-  mb_free(tsd);
-}
-
-void
-cmd_show_threads(int show_loops)
-{
-  struct bird_thread_show_data *tsd = mb_allocz(&root_pool, sizeof(struct bird_thread_show_data));
-  tsd->cli = this_cli;
-  tsd->show_loops = show_loops;
-  tsd->line_pos = 0;
-  tsd->line_max = 64;
-
-  this_cli->cont = bird_thread_show_cli_cont;
-  this_cli->cleanup = bird_thread_show_cli_cleanup;
-
-  bird_thread_sync_all(&tsd->sync, bird_thread_show, cmd_show_threads_done, "Show Threads");
-}
-
 bool task_still_in_limit(void)
 {
   static u64 main_counter = 0;
index f7fde411b6c817d3d0e62baeab4f294aac5f5c84..a017244c153e5fc0dc13edd15931bba933d1de03 100644 (file)
@@ -103,6 +103,7 @@ struct bird_thread
   struct spent_time overhead, idle;
 };
 
+extern _Thread_local struct bird_thread *this_thread;
 
 struct bird_thread_syncer {
   pool *pool;
@@ -117,4 +118,18 @@ void bird_thread_sync_all(struct bird_thread_syncer *sync,
     void (*hook)(struct bird_thread_syncer *),
     void (*done)(struct bird_thread_syncer *), const char *name);
 
+struct birdloop_pickup_group {
+  DOMAIN(attrs) domain;
+  list loops;
+  list threads;
+  uint thread_count;
+  uint thread_busy_count;
+  uint loop_count;
+  uint loop_unassigned_count;
+  btime max_latency;
+  event start_threads;
+};
+
+extern struct birdloop_pickup_group pickup_groups[2];
+
 #endif