]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Co-routines moved to a separate module with sysdep implementation
authorMartin Mares <mj@ucw.cz>
Tue, 18 Jul 2017 21:01:06 +0000 (23:01 +0200)
committerMartin Mares <mj@ucw.cz>
Tue, 18 Jul 2017 21:01:06 +0000 (23:01 +0200)
lib/coroutine.h [new file with mode: 0644]
nest/cli.c
sysdep/unix/Makefile
sysdep/unix/coroutine.c [new file with mode: 0644]
sysdep/unix/io.c
sysdep/unix/main.c
sysdep/unix/unix.h

diff --git a/lib/coroutine.h b/lib/coroutine.h
new file mode 100644 (file)
index 0000000..f64a954
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *     BIRD Coroutines
+ *
+ *     (c) 2017 Martin Mares <mj@ucw.cz>
+ *
+ *     Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_COROUTINE_H_
+#define _BIRD_COROUTINE_H_
+
+// The structure is completely opaque, implemented by sysdep
+typedef struct coroutine coroutine;
+
+coroutine *coro_new(struct pool *pool, void (*entry_point)(void *arg), void *arg);
+void coro_suspend(void);
+void coro_resume(coroutine *c);
+
+struct birdsock;
+int coro_sk_read(struct birdsock *s);
+
+#endif
index b8f6956cf6a3562e66798c119e244266c004d4bc..bf4b47a8f9b345615e2c9659d7f01b057a6a1711 100644 (file)
@@ -66,8 +66,8 @@
 #include "nest/bird.h"
 #include "nest/cli.h"
 #include "conf/conf.h"
+#include "lib/coroutine.h"
 #include "lib/string.h"
-#include "sysdep/unix/unix.h"  // FIXME
 
 pool *cli_pool;
 
index f592399c1ba85c8cbda5b4c899301bfddd025942..9da836133c5d63b197279b936af41eea00b88453 100644 (file)
@@ -1,4 +1,4 @@
-src := io.c krt.c log.c main.c random.c
+src := io.c krt.c log.c main.c random.c coroutine.c
 obj := $(src-o-files)
 $(all-daemon)
 $(cf-local)
diff --git a/sysdep/unix/coroutine.c b/sysdep/unix/coroutine.c
new file mode 100644 (file)
index 0000000..3d648eb
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ *     BIRD Coroutines
+ *
+ *     (c) 2017 Martin Mares <mj@ucw.cz>
+ *
+ *     Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdlib.h>
+#include <ucontext.h>
+
+#include "nest/bird.h"
+#include "lib/coroutine.h"
+#include "lib/resource.h"
+#include "lib/socket.h"
+#include "sysdep/unix/unix.h"
+
+struct coroutine {
+  resource r;
+  ucontext_t ctx;
+  void *stack;
+  void (*entry_point)(void *arg);
+  void *arg;
+};
+
+static ucontext_t *main_context;
+static coroutine *coro_current;                // NULL for main context
+
+#define CORO_STACK_SIZE 65536
+
+static void
+coro_free(resource *r)
+{
+  coroutine *c = (coroutine *) r;
+  xfree(c->stack);
+}
+
+static void
+coro_dump(resource *r UNUSED)
+{
+  debug("\n");
+}
+
+static size_t
+coro_memsize(resource *r)
+{
+  coroutine *c = (coroutine *) r;
+  return sizeof(*c) + CORO_STACK_SIZE + 2*ALLOC_OVERHEAD;
+}
+
+static struct resclass coro_class = {
+  .name = "Coroutine",
+  .size = sizeof(struct coroutine),
+  .free = coro_free,
+  .dump = coro_dump,
+  .memsize = coro_memsize,
+};
+
+static void
+coro_do_start(void)
+{
+  ASSERT(coro_current);
+  coro_current->entry_point(coro_current->arg);
+  bug("Coroutine returned unexpectedly");
+}
+
+struct coroutine *
+coro_new(pool *p, void (*entry_point)(void *), void *arg)
+{
+  if (!main_context)
+    {
+      main_context = xmalloc(sizeof(*main_context));
+      if (getcontext(main_context) < 0)
+       bug("getcontext() failed");
+    }
+
+  coroutine *c = ralloc(p, &coro_class);
+  c->entry_point = entry_point;
+  c->arg = arg;
+  if (getcontext(&c->ctx) < 0)
+    bug("getcontext() failed");
+  c->stack = xmalloc(CORO_STACK_SIZE);
+  c->ctx.uc_stack.ss_sp = c->stack;
+  c->ctx.uc_stack.ss_size = CORO_STACK_SIZE;
+
+  makecontext(&c->ctx, coro_do_start, 0);
+
+  return c;
+}
+
+void
+coro_suspend(void)
+{
+  ASSERT(coro_current);
+  ASSERT(main_context);
+  coroutine *c = coro_current;
+  coro_current = NULL;
+  swapcontext(&c->ctx, main_context);
+  ASSERT(coro_current == c);
+}
+
+void
+coro_resume(coroutine *c)
+{
+  ASSERT(!coro_current);
+  coro_current = c;
+  swapcontext(main_context, &c->ctx);
+  ASSERT(!coro_current);
+}
+
+/* Coroutine-based I/O */
+
+static int
+coro_sk_rx_hook(sock *sk, uint size UNUSED)
+{
+  ASSERT(sk->rx_coroutine);
+  ASSERT(!coro_current);
+  coro_resume(sk->rx_coroutine);
+  return 0;
+}
+
+int
+coro_sk_read(sock *s)
+{
+  ASSERT(coro_current);
+  s->rx_coroutine = coro_current;
+  s->rx_hook = coro_sk_rx_hook;
+  coro_suspend();
+  s->rx_hook = NULL;
+  return s->rpos - s->rbuf;
+}
index 44d0d8b559b8cb663e0571fc61c8b60579b1615e..0cf48c9dd9953c5ef3654ccd6d8bcca2a7277027 100644 (file)
@@ -2665,113 +2665,3 @@ test_old_bird(char *path)
     die("I found another BIRD running.");
   close(fd);
 }
-
-/* EXPERIMENTAL: Support for coroutines */
-
-#include <ucontext.h>
-
-struct coroutine {
-  resource r;
-  ucontext_t ctx;
-  void *stack;
-  void (*entry_point)(void *arg);
-  void *arg;
-};
-
-static ucontext_t *main_context;
-static coroutine *coro_current;        // NULL for main context
-
-static void
-coro_free(resource *r)
-{
-  coroutine *c = (coroutine *) r;
-  xfree(c->stack);
-}
-
-static void
-coro_dump(resource *r UNUSED)
-{
-  debug("\n");
-}
-
-static struct resclass coro_class = {
-  .name = "Coroutine",
-  .size = sizeof(struct coroutine),
-  .free = coro_free,
-  .dump = coro_dump,
-  // FIXME: Implement memsize
-};
-
-static void
-coro_do_start(void)
-{
-  ASSERT(coro_current);
-  coro_current->entry_point(coro_current->arg);
-  bug("Coroutine returned unexpectedly");
-}
-
-struct coroutine *
-coro_new(pool *p, void (*entry_point)(void *), void *arg)
-{
-  if (!main_context)
-    {
-      main_context = xmalloc(sizeof(*main_context));
-      if (getcontext(main_context) < 0)
-       bug("getcontext() failed");
-    }
-
-  coroutine *c = ralloc(p, &coro_class);
-  c->entry_point = entry_point;
-  c->arg = arg;
-  if (getcontext(&c->ctx) < 0)
-    bug("getcontext() failed");
-  c->stack = xmalloc(65536);
-  c->ctx.uc_stack.ss_sp = c->stack;
-  c->ctx.uc_stack.ss_size = 65536;
-
-  makecontext(&c->ctx, coro_do_start, 0);
-
-  return c;
-}
-
-// Return to main context
-void
-coro_suspend(void)
-{
-  ASSERT(coro_current);
-  ASSERT(main_context);
-  coroutine *c = coro_current;
-  coro_current = NULL;
-  swapcontext(&c->ctx, main_context);
-  ASSERT(coro_current == c);
-}
-
-// Resume context
-void
-coro_resume(coroutine *c)
-{
-  ASSERT(!coro_current);
-  coro_current = c;
-  swapcontext(main_context, &c->ctx);
-  ASSERT(!coro_current);
-}
-
-static int
-coro_sk_rx_hook(sock *sk, uint size UNUSED)
-{
-  ASSERT(sk->rx_coroutine);
-  ASSERT(!coro_current);
-  coro_resume(sk->rx_coroutine);
-  return 0;
-}
-
-int
-coro_sk_read(sock *s)
-{
-  ASSERT(coro_current);
-  s->rx_coroutine = coro_current;
-  s->rx_hook = coro_sk_rx_hook;
-  coro_suspend();
-  s->rx_hook = NULL;
-  return s->rpos - s->rbuf;
-}
index c625a859aa36f3e79a4e2071aa735e23d0f0cbfa..35615831765dab19b40f9e9a505d857dfb8355a0 100644 (file)
@@ -23,6 +23,7 @@
 #include <libgen.h>
 
 #include "nest/bird.h"
+#include "lib/coroutine.h"
 #include "lib/lists.h"
 #include "lib/resource.h"
 #include "lib/socket.h"
index 4a9b425360964bcb38f996a899bd873b7d7bca4b..dcaab72973612e3bbcceb16f2f687ce41338990c 100644 (file)
@@ -102,13 +102,6 @@ int sk_open_unix(struct birdsock *s, char *name);
 void *tracked_fopen(struct pool *, char *name, char *mode);
 void test_old_bird(char *path);
 
-/* Co-routines */
-typedef struct coroutine coroutine;
-coroutine *coro_new(struct pool *pool, void (*entry_point)(void *arg), void *arg);
-void coro_suspend(void);
-void coro_resume(coroutine *c);
-int coro_sk_read(struct birdsock *s);
-
 /* krt.c bits */
 
 void krt_io_init(void);