]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Moved the thread starting code to IO loop code
authorMaria Matejka <mq@ucw.cz>
Thu, 28 Jul 2022 17:49:03 +0000 (19:49 +0200)
committerMaria Matejka <mq@ucw.cz>
Thu, 28 Jul 2022 17:49:03 +0000 (19:49 +0200)
lib/coro.h [deleted file]
lib/timer.c
lib/timer.h
nest/proto.c
nest/protocol.h
nest/rt-table.c
sysdep/unix/Makefile
sysdep/unix/domain.c [moved from sysdep/unix/coroutine.c with 64% similarity]
sysdep/unix/io-loop.c
sysdep/unix/io-loop.h
sysdep/unix/log.c

diff --git a/lib/coro.h b/lib/coro.h
deleted file mode 100644 (file)
index 17ccff8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *     BIRD Coroutines
- *
- *     (c) 2017 Martin Mares <mj@ucw.cz>
- *     (c) 2020-2021 Maria Matejka <mq@jmq.cz>
- *
- *     Can be freely distributed and used under the terms of the GNU GPL.
- */
-
-#ifndef _BIRD_CORO_H_
-#define _BIRD_CORO_H_
-
-#include "lib/resource.h"
-
-/* A completely opaque coroutine handle. */
-struct coroutine;
-
-/* Coroutines are independent threads bound to pools.
- * You request a coroutine by calling coro_run().
- * It is forbidden to free a running coroutine from outside.
- * The running coroutine must free itself by rfree() before returning.
- */
-struct coroutine *coro_run(pool *, void (*entry)(void *), void *data);
-
-/* Get self. */
-extern _Thread_local struct coroutine *this_coro;
-
-
-#endif
index c1241ba7da213a2befa9b187d244313273b3f824..ff6975a4a02bd2002720c9a5ccc26f3815d2574b 100644 (file)
@@ -32,7 +32,6 @@
 
 #include "nest/bird.h"
 
-#include "lib/coro.h"
 #include "lib/heap.h"
 #include "lib/resource.h"
 #include "lib/timer.h"
@@ -117,7 +116,7 @@ tm_set_in_tl(timer *t, btime when, struct timeloop *local_timeloop)
 
   t->loop = local_timeloop;
 
-  if ((t->index == 1) && (local_timeloop->coro != this_coro))
+  if (t->index == 1)
     birdloop_ping(local_timeloop->loop);
 }
 
index 04544ace1a8ef5ac583e91a68d639328fd37a675..555fc96f7e767d9f67ac9bad418fd63142611a2c 100644 (file)
@@ -41,7 +41,6 @@ struct timeloop
   BUFFER_(timer *) timers;
   struct domain_generic *domain;
   struct birdloop *loop;
-  struct coroutine *coro;
 };
 
 #define TLOCK_TIMER_ASSERT(loop) ASSERT_DIE((loop)->domain && DG_IS_LOCKED((loop)->domain))
index 17cd08f7998b141d9e6bac53e256ecc367b730a5..1d480ba23f34b31b4f2915ac3b4b662ac6582bfd 100644 (file)
@@ -15,7 +15,6 @@
 #include "lib/event.h"
 #include "lib/timer.h"
 #include "lib/string.h"
-#include "lib/coro.h"
 #include "conf/conf.h"
 #include "nest/rt.h"
 #include "nest/iface.h"
index d6224015642bde6efb35470c4620d99f086d8a70..3c823ae11d860aa3fb374ce7d582ee6e3d24fdf9 100644 (file)
@@ -134,7 +134,7 @@ struct proto {
   u32 debug;                           /* Debugging flags */
   u32 mrtdump;                         /* MRTDump flags */
   uint active_channels;                        /* Number of active channels */
-  uint active_coroutines;              /* Number of active coroutines */
+  uint active_loops;                   /* Number of active IO loops */
   byte net_type;                       /* Protocol network type (NET_*), 0 for undefined */
   byte disabled;                       /* Manually disabled */
   byte vrf_set;                                /* Related VRF instance (above) is defined */
@@ -342,7 +342,7 @@ void proto_notify_state(struct proto *p, unsigned state);
  */
 
 static inline int proto_is_inactive(struct proto *p)
-{ return (p->active_channels == 0) && (p->active_coroutines == 0); }
+{ return (p->active_channels == 0) && (p->active_loops == 0); }
 
 
 /*
index ca09267885a67094fe708c60f0d2167b7ff50bea..65fc142a57bd97cb64093d5458db19f30d39639d 100644 (file)
@@ -1984,7 +1984,7 @@ rt_export_stopped(void *data)
   /* Reporting the hook as finished. */
   CALL(tab->done, hook);
 
-  /* Free the hook together with its coroutine. */
+  /* Free the hook. */
   rfree(hook->pool);
 }
 
index 9831dc961803b547e835ab84657c18442d5a13f4..3f1a8b3ac22a2a215476ca2ddba47fe34fd86f55 100644 (file)
@@ -1,4 +1,4 @@
-src := alloc.c io.c io-loop.c krt.c log.c main.c random.c coroutine.c
+src := alloc.c io.c io-loop.c krt.c log.c main.c random.c domain.c
 obj := $(src-o-files)
 $(all-daemon)
 $(cf-local)
similarity index 64%
rename from sysdep/unix/coroutine.c
rename to sysdep/unix/domain.c
index 4758c056711c64c79def9039aa8f369c1c4bbf19..0a5858a6805815d2080d8f9cb4897a4900f39d11 100644 (file)
@@ -1,7 +1,6 @@
 /*
- *     BIRD Coroutines
+ *     BIRD Locking
  *
- *     (c) 2017 Martin Mares <mj@ucw.cz>
  *     (c) 2020 Maria Matejka <mq@jmq.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
 
 #include "lib/birdlib.h"
 #include "lib/locking.h"
-#include "lib/coro.h"
 #include "lib/resource.h"
 #include "lib/timer.h"
 
 #include "conf/conf.h"
 
-#define CORO_STACK_SIZE        65536
-
-/*
- *     Implementation of coroutines based on POSIX threads
- */
-
 #include <errno.h>
 #include <fcntl.h>
 #include <poll.h>
@@ -122,71 +114,3 @@ void do_unlock(struct domain_generic *dg, struct domain_generic **lsp)
   dg->prev = NULL;
   pthread_mutex_unlock(&dg->mutex);
 }
-
-/* Coroutines */
-struct coroutine {
-  resource r;
-  pthread_t id;
-  pthread_attr_t attr;
-  void (*entry)(void *);
-  void *data;
-};
-
-static _Thread_local _Bool coro_cleaned_up = 0;
-
-static void coro_free(resource *r)
-{
-  struct coroutine *c = (void *) r;
-  ASSERT_DIE(pthread_equal(pthread_self(), c->id));
-  pthread_attr_destroy(&c->attr);
-  coro_cleaned_up = 1;
-}
-
-static struct resclass coro_class = {
-  .name = "Coroutine",
-  .size = sizeof(struct coroutine),
-  .free = coro_free,
-};
-
-_Thread_local struct coroutine *this_coro = NULL;
-
-static void *coro_entry(void *p)
-{
-  struct coroutine *c = p;
-
-  ASSERT_DIE(c->entry);
-
-  this_coro = c;
-
-  c->entry(c->data);
-  ASSERT_DIE(coro_cleaned_up);
-
-  return NULL;
-}
-
-struct coroutine *coro_run(pool *p, void (*entry)(void *), void *data)
-{
-  ASSERT_DIE(entry);
-  ASSERT_DIE(p);
-
-  struct coroutine *c = ralloc(p, &coro_class);
-
-  c->entry = entry;
-  c->data = data;
-
-  int e = 0;
-
-  if (e = pthread_attr_init(&c->attr))
-    die("pthread_attr_init() failed: %M", e);
-
-  if (e = pthread_attr_setstacksize(&c->attr, CORO_STACK_SIZE))
-    die("pthread_attr_setstacksize(%u) failed: %M", CORO_STACK_SIZE, e);
-
-  if (e = pthread_attr_setdetachstate(&c->attr, PTHREAD_CREATE_DETACHED))
-    die("pthread_attr_setdetachstate(PTHREAD_CREATE_DETACHED) failed: %M", e);
-
-  if (e = pthread_create(&c->id, &c->attr, coro_entry, c))
-    die("pthread_create() failed: %M", e);
-
-  return c;
-}
index dfb2ce49a8dc6452ac210dcbb11d71386a64bef8..3419d9d84ba70d8f8ac31639e5d6224b890870a7 100644 (file)
@@ -17,7 +17,6 @@
 #include "nest/bird.h"
 
 #include "lib/buffer.h"
-#include "lib/coro.h"
 #include "lib/lists.h"
 #include "lib/resource.h"
 #include "lib/event.h"
@@ -28,6 +27,8 @@
 #include "sysdep/unix/io-loop.h"
 #include "conf/conf.h"
 
+#define THREAD_STACK_SIZE      65536   /* To be lowered in near future */
+
 /*
  *     Current thread context
  */
@@ -132,11 +133,10 @@ wakeup_do_kick(struct birdloop *loop)
   pipe_kick(loop->wakeup_fds[1]);
 }
 
-void
-birdloop_ping(struct birdloop *loop)
+static inline void
+birdloop_do_ping(struct birdloop *loop)
 {
-  u32 ping_sent = atomic_fetch_add_explicit(&loop->ping_sent, 1, memory_order_acq_rel);
-  if (ping_sent)
+  if (atomic_fetch_add_explicit(&loop->ping_sent, 1, memory_order_acq_rel))
     return;
 
   if (loop == birdloop_wakeup_masked)
@@ -145,6 +145,15 @@ birdloop_ping(struct birdloop *loop)
     wakeup_do_kick(loop);
 }
 
+void
+birdloop_ping(struct birdloop *loop)
+{
+  if (birdloop_inside(loop) && !loop->ping_pending)
+    loop->ping_pending++;
+  else
+    birdloop_do_ping(loop);
+}
+
 
 /*
  *     Sockets
@@ -336,7 +345,7 @@ birdloop_init(void)
   birdloop_enter_locked(&main_birdloop);
 }
 
-static void birdloop_main(void *arg);
+static void *birdloop_main(void *arg);
 
 struct birdloop *
 birdloop_new(pool *pp, uint order, const char *name)
@@ -357,7 +366,19 @@ birdloop_new(pool *pp, uint order, const char *name)
   timers_init(&loop->time, p);
   sockets_init(loop);
 
-  loop->time.coro = coro_run(p, birdloop_main, loop);
+  int e = 0;
+
+  if (e = pthread_attr_init(&loop->thread_attr))
+    die("pthread_attr_init() failed: %M", e);
+
+  if (e = pthread_attr_setstacksize(&loop->thread_attr, THREAD_STACK_SIZE))
+    die("pthread_attr_setstacksize(%u) failed: %M", THREAD_STACK_SIZE, e);
+
+  if (e = pthread_attr_setdetachstate(&loop->thread_attr, PTHREAD_CREATE_DETACHED))
+    die("pthread_attr_setdetachstate(PTHREAD_CREATE_DETACHED) failed: %M", e);
+
+  if (e = pthread_create(&loop->thread_id, &loop->thread_attr, birdloop_main, loop))
+    die("pthread_create() failed: %M", e);
 
   birdloop_leave(loop);
 
@@ -393,6 +414,10 @@ void
 birdloop_free(struct birdloop *loop)
 {
   ASSERT_DIE(loop->links == 0);
+  ASSERT_DIE(pthread_equal(pthread_self(), loop->thread_id));
+
+  pthread_attr_destroy(&loop->thread_attr);
+
   domain_free(loop->time.domain);
   rfree(loop->pool);
 }
@@ -423,6 +448,13 @@ birdloop_leave_locked(struct birdloop *loop)
   /* Check the current context */
   ASSERT_DIE(birdloop_current == loop);
 
+  /* Send pending pings */
+  if (loop->ping_pending)
+  {
+    loop->ping_pending = 0;
+    birdloop_do_ping(loop);
+  }
+
   /* Restore the old context */
   birdloop_current = loop->prev_loop;
 }
@@ -466,7 +498,7 @@ birdloop_unlink(struct birdloop *loop)
   loop->links--;
 }
 
-static void
+static void *
 birdloop_main(void *arg)
 {
   struct birdloop *loop = arg;
@@ -532,6 +564,8 @@ birdloop_main(void *arg)
 
   birdloop_leave(loop);
   loop->stopped(loop->stop_data);
+
+  return NULL;
 }
 
 
index 4024b6c5715c304386c1f9dccc8e6e9f3d1d1a18..ca4322fce10c6c450b9be7cc9719a7941aa0929f 100644 (file)
@@ -21,9 +21,13 @@ struct birdloop
   u8 poll_changed;
   u8 close_scheduled;
 
+  uint ping_pending;
   _Atomic u32 ping_sent;
   int wakeup_fds[2];
 
+  pthread_t thread_id;
+  pthread_attr_t thread_attr;
+
   uint links;
 
   void (*stopped)(void *data);
index f48588b6175712522a9ba30fe0a9f1254813e533..185231e8777731e8777cfe7476dc1dfc1b24e7ac 100644 (file)
@@ -36,10 +36,10 @@ static FILE *dbgf;
 static list *current_log_list;
 static char *current_syslog_name; /* NULL -> syslog closed */
 
-static _Atomic uint max_coro_id = ATOMIC_VAR_INIT(1);
-static _Thread_local uint this_coro_id;
+static _Atomic uint max_thread_id = ATOMIC_VAR_INIT(1);
+static _Thread_local uint this_thread_id;
 
-#define THIS_CORO_ID  (this_coro_id ?: (this_coro_id = atomic_fetch_add_explicit(&max_coro_id, 1, memory_order_acq_rel)))
+#define THIS_THREAD_ID  (this_thread_id ?: (this_thread_id = atomic_fetch_add_explicit(&max_thread_id, 1, memory_order_acq_rel)))
 
 #include <pthread.h>
 
@@ -183,7 +183,7 @@ log_commit(int class, buffer *buf)
                l->pos += msg_len;
              }
 
-             fprintf(l->fh, "%s [%04x] <%s> ", tbuf, THIS_CORO_ID, class_names[class]);
+             fprintf(l->fh, "%s [%04x] <%s> ", tbuf, THIS_THREAD_ID, class_names[class]);
            }
          fputs(buf->start, l->fh);
          fputc('\n', l->fh);
@@ -329,7 +329,7 @@ debug(const char *msg, ...)
        sec = dbg_time.tv_sec - dbg_time_start.tv_sec - 1;
       }
 
-      int n = bsnprintf(pos, max, "%u.%09u: [%04x] ", sec, nsec, THIS_CORO_ID);
+      int n = bsnprintf(pos, max, "%u.%09u: [%04x] ", sec, nsec, THIS_THREAD_ID);
       pos += n;
       max -= n;