]> granicus.if.org Git - pdns/commitdiff
Initial stab at Boost context backend for MTasker
authorAndrew Nelless <andrew@nelless.net>
Mon, 22 Feb 2016 16:49:24 +0000 (16:49 +0000)
committerAndrew Nelless <andrew@nelless.net>
Mon, 22 Feb 2016 21:11:35 +0000 (21:11 +0000)
pdns/mtasker_fcontext.cc [new file with mode: 0644]
pdns/recursordist/Makefile.am
pdns/recursordist/configure.ac
pdns/recursordist/mtasker_fcontext.cc [new symlink]

diff --git a/pdns/mtasker_fcontext.cc b/pdns/mtasker_fcontext.cc
new file mode 100644 (file)
index 0000000..dfe3455
--- /dev/null
@@ -0,0 +1,71 @@
+#include "mtasker_context.hh"
+#include <exception>
+#include <cassert>
+#include <boost/context/fcontext.hpp>
+
+using boost::context::fcontext_t;
+using boost::context::jump_fcontext;
+using boost::context::make_fcontext;
+
+struct args_t {
+    fcontext_t prev_ctx = nullptr;
+    pdns_ucontext_t* self = nullptr;
+    std::function<void(void)>* work = nullptr;
+};
+
+extern "C" {
+static
+void
+threadWrapper (intptr_t const xargs) {
+    auto args = reinterpret_cast<args_t*>(xargs);
+    auto ctx = args->self;
+    auto work = args->work;
+    jump_fcontext (&ctx->uc_mcontext, args->prev_ctx, 0);
+    args = nullptr;
+
+    try {
+        auto start = std::move (*work);
+        start();
+    } catch (...) {
+        ctx->exception = std::current_exception();
+    }
+
+    auto const next_ctx = ctx->uc_link->uc_mcontext;
+    jump_fcontext (&ctx->uc_mcontext, next_ctx,
+                   static_cast<bool>(ctx->exception));
+#ifdef NDEBUG
+    __builtin_unreachable();
+#endif
+}
+}
+
+pdns_ucontext_t::pdns_ucontext_t
+(): uc_mcontext(nullptr), uc_link(nullptr) {
+}
+
+pdns_ucontext_t::~pdns_ucontext_t
+() {
+}
+
+void
+pdns_swapcontext
+(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx) {
+    if (jump_fcontext (&octx.uc_mcontext, ctx.uc_mcontext, 0)) {
+        std::rethrow_exception (ctx.exception);
+    }
+}
+
+void
+pdns_makecontext
+(pdns_ucontext_t& ctx, std::function<void(void)>& start) {
+    assert (ctx.uc_link);
+    assert (ctx.uc_stack.size() >= 8192);
+    assert (!ctx.uc_mcontext);
+    ctx.uc_mcontext = make_fcontext (&ctx.uc_stack[ctx.uc_stack.size()],
+                                     ctx.uc_stack.size(), &threadWrapper);
+    args_t args;
+    args.self = &ctx;
+    args.work = &start;
+    jump_fcontext (&args.prev_ctx, ctx.uc_mcontext,
+                   reinterpret_cast<intptr_t>(&args));
+}
index 48b256030660f12398433dbbd8523cc4f8b9e72e..c73e1d6a6bbc1b6031c438dcf43897dd3383ebf9 100644 (file)
@@ -85,7 +85,7 @@ pdns_recursor_SOURCES = \
        misc.hh misc.cc \
        mplexer.hh \
        mtasker.hh \
-       mtasker_context.hh mtasker_ucontext.cc \
+       mtasker_context.hh mtasker_fcontext.cc \
        namespaces.hh \
        nsecrecords.cc \
        opensslsigners.cc opensslsigners.hh \
@@ -127,7 +127,8 @@ pdns_recursor_SOURCES = \
 pdns_recursor_LDADD = \
        $(YAHTTP_LIBS) \
        $(JSON11_LIBS) \
-       $(OPENSSL_LIBS)
+       $(OPENSSL_LIBS) \
+       $(BOOST_CONTEXT_LIBS)
 
 pdns_recursor_LDFLAGS = $(AM_LDFLAGS) \
        $(OPENSSL_LDFLAGS)
index 880a99345d5b9d3affca38de2f1d9423068b3118..72753c92d2aa452c38da23da2ecd6f7c79bdcfe3 100644 (file)
@@ -34,6 +34,7 @@ AC_PROG_LIBTOOL
 PDNS_CHECK_OS
 
 BOOST_REQUIRE([1.35])
+BOOST_CONTEXT()
 PDNS_ENABLE_REPRODUCIBLE
 
 PDNS_WITH_LUAJIT
diff --git a/pdns/recursordist/mtasker_fcontext.cc b/pdns/recursordist/mtasker_fcontext.cc
new file mode 120000 (symlink)
index 0000000..cac593d
--- /dev/null
@@ -0,0 +1 @@
+../mtasker_fcontext.cc
\ No newline at end of file