BIND 10 trac2874, updated. 269b0ac0f5de7ff21ae8cf68e6677a4809b8d5a0 [2874] Implement the coroutine body
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Jul 17 15:28:33 UTC 2013
The branch, trac2874 has been updated
via 269b0ac0f5de7ff21ae8cf68e6677a4809b8d5a0 (commit)
via 8bb93d97eea503d2642e96f34bbbe796aea22db4 (commit)
via 157a503e74905d8a475437f65744aa0fa1810629 (commit)
from 2621cb25329d49ccf48ba515e4aa2cbdf8579c9c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 269b0ac0f5de7ff21ae8cf68e6677a4809b8d5a0
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Jul 17 17:24:58 2013 +0200
[2874] Implement the coroutine body
Implement the handling of the query. This is just the loop that does the
real logic, asynchronous handling is left for the scheduler (TBD).
commit 8bb93d97eea503d2642e96f34bbbe796aea22db4
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Jul 17 17:23:01 2013 +0200
[2874] Skip coroutines benchmark if no lib
Skip the coroutines resolver benchmark during the compilation, if the
boost coroutines library is not available.
The -lboost_context is needed to link it. It is not clear if any more
flags (like paths) need to be used on some systems, this is just
guesswork to make it work locally.
Some better detection or configure switch TBD here.
commit 157a503e74905d8a475437f65744aa0fa1810629
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Jul 17 17:22:38 2013 +0200
[2874] Detect if boost coroutines are available
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 7 +++
m4macros/ax_boost_for_bind10.m4 | 11 +++++
src/bin/resolver/bench/Makefile.am | 6 ++-
src/bin/resolver/bench/coroutine_resolver.cc | 67 +++++++++++++++++++++++++-
src/bin/resolver/bench/coroutine_resolver.h | 5 ++
5 files changed, 94 insertions(+), 2 deletions(-)
-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 72a825e..2c542ee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -898,6 +898,13 @@ if test "$BOOST_NUMERIC_CAST_WOULDFAIL" = "yes" -a X"$werror_ok" = X1 -a $CLANGP
AC_MSG_ERROR([Failed to compile a required header file. If you are using FreeBSD and Boost installed via ports, retry with specifying --without-werror. See the ChangeLog entry for Trac no. 1991 for more details.])
fi
+# Some systems are missing boost coroutines. We don't fail for that, as they are
+# used just in some internal benchmark for now.
+AM_CONDITIONAL([BOOST_COROUTINES], [test "$BOOST_COROUTINES" = "yes"])
+if test "$BOOST_COROUTINES" = "yes" ; then
+ AC_DEFINE(BOOST_COROUTINES, 1, [Define to 1 if boost::coroutine library works])
+fi
+
use_shared_memory=yes
AC_ARG_WITH(shared-memory,
AC_HELP_STRING([--with-shared-memory],
diff --git a/m4macros/ax_boost_for_bind10.m4 b/m4macros/ax_boost_for_bind10.m4
index 3a71337..1511b5c 100644
--- a/m4macros/ax_boost_for_bind10.m4
+++ b/m4macros/ax_boost_for_bind10.m4
@@ -30,6 +30,8 @@ dnl compile managed_mapped_file (can be empty).
dnl It is of no use if "WOULDFAIL" is yes.
dnl BOOST_STATIC_ASSERT_WOULDFAIL set to "yes" if BOOST_STATIC_ASSERT would
dnl cause build error; otherwise set to "no"
+dnl BOOST_COROUTINES set to "yes" if the boost coroutines are available,
+dnl no otherwise.
AC_DEFUN([AX_BOOST_FOR_BIND10], [
AC_LANG_SAVE
@@ -160,6 +162,15 @@ void testfn(void) { BOOST_STATIC_ASSERT(true); }
[AC_MSG_RESULT(no)
BOOST_STATIC_ASSERT_WOULDFAIL=yes])
+AC_MSG_CHECKING([BOOST_COROUTINES compiles])
+AC_TRY_COMPILE([
+#include <boost/coroutine/all.hpp>
+],,
+[AC_MSG_RESULT(yes)
+ BOOST_COROUTINES=yes],
+[AC_MSG_RESULT(no)
+ BOOST_COROUTINES=no])
+
CXXFLAGS="$CXXFLAGS_SAVED"
AC_SUBST(BOOST_INCLUDES)
diff --git a/src/bin/resolver/bench/Makefile.am b/src/bin/resolver/bench/Makefile.am
index c3b2bdd..c2183cb 100644
--- a/src/bin/resolver/bench/Makefile.am
+++ b/src/bin/resolver/bench/Makefile.am
@@ -18,8 +18,12 @@ resolver_bench_SOURCES = main.cc
resolver_bench_SOURCES += fake_resolution.h fake_resolution.cc
resolver_bench_SOURCES += dummy_work.h dummy_work.cc
resolver_bench_SOURCES += naive_resolver.h naive_resolver.cc
+if BOOST_COROUTINES
resolver_bench_SOURCES += coroutine_resolver.h coroutine_resolver.cc
+endif
resolver_bench_LDADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
resolver_bench_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
-
+if BOOST_COROUTINES
+resolver_bench_LDADD += -lboost_context
+endif
diff --git a/src/bin/resolver/bench/coroutine_resolver.cc b/src/bin/resolver/bench/coroutine_resolver.cc
index 16c3911..baf41f8 100644
--- a/src/bin/resolver/bench/coroutine_resolver.cc
+++ b/src/bin/resolver/bench/coroutine_resolver.cc
@@ -18,8 +18,10 @@
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
+#include <boost/coroutine/all.hpp>
using isc::util::thread::Thread;
+using isc::util::thread::Mutex;
namespace isc {
namespace resolver {
@@ -42,9 +44,72 @@ CoroutineResolver::~CoroutineResolver() {
}
}
+namespace {
+
+// This is the callback passed to the AsyncWork. It'll be provided by
+// the scheduler and it will restore the coroutine.
+typedef boost::function<void()> SimpleCallback;
+// A bit of asynchronous work to be performed. The coroutine will
+// return this functor to the scheduler. The scheduler will execute
+// it and pass it a callback that should be executed once the work
+// is done, to reschedule.
+typedef boost::function<void(SimpleCallback)> AsyncWork;
+// A single coroutine, doing some work.
+typedef boost::coroutines::coroutine<AsyncWork()> Coroutine;
+
void
-CoroutineResolver::run_instance(FakeInterface*) {
+doneTask(bool* flag) {
+ *flag = true;
+}
+void
+performUpstream(const FakeQueryPtr& query, Mutex* mutex,
+ const SimpleCallback& callback)
+{
+ Mutex::Locker locker(*mutex);
+ query->performTask(callback);
+}
+
+// Handle one query on the given interface. The cache is locked
+// by the cache mutex (for write), sending of the upstream query
+// by the upstream_mutex.
+void handleQuery(FakeQueryPtr query, Mutex& cache_mutex, Mutex& upstream_mutex,
+ Coroutine::caller_type& scheduler)
+{
+ while (!query->done()) {
+ switch (query->nextTask()) {
+ case CacheWrite: {
+ // We need to lock the cache when writing (but not for reading)
+ Mutex::Locker locker(cache_mutex);
+ bool done = false;
+ query->performTask(boost::bind(&doneTask, &done));
+ assert(done); // Write to cache is synchronous.
+ break;
+ }
+ case Upstream:
+ // Schedule sending to upstream and get resumed afterwards.
+
+ // This could probably be done with nested boost::bind, but
+ // that'd get close to unreadable, so we are more conservative
+ // and use a function.
+ scheduler(boost::bind(&performUpstream, query, &upstream_mutex,
+ _1));
+ // Good, answer returned now. Continue processing.
+ break;
+ default:
+ // Nothing special here. We just perform the task.
+ bool done = false;
+ query->performTask(boost::bind(&doneTask, &done));
+ assert(done);
+ break;
+ }
+ }
+}
+
+}
+
+void
+CoroutineResolver::run_instance(FakeInterface*) {
}
size_t
diff --git a/src/bin/resolver/bench/coroutine_resolver.h b/src/bin/resolver/bench/coroutine_resolver.h
index 6efc5d0..24ff71d 100644
--- a/src/bin/resolver/bench/coroutine_resolver.h
+++ b/src/bin/resolver/bench/coroutine_resolver.h
@@ -17,6 +17,8 @@
#include <resolver/bench/fake_resolution.h>
+#include <util/threads/sync.h>
+
#include <boost/noncopyable.hpp>
#include <vector>
@@ -47,6 +49,9 @@ public:
private:
// Run one thread on given interface.
void run_instance(FakeInterface* interface);
+ // Mutex for locking write access to the cache and the upstream
+ // communication.
+ isc::util::thread::Mutex cache_mutex_, upstream_mutex_;
std::vector<FakeInterface*> interfaces_;
const size_t thread_count_;
const size_t total_count_;
More information about the bind10-changes
mailing list