diff options
-rw-r--r-- | libadhocutil/Jamfile.jam | 2 | ||||
-rw-r--r-- | libadhocutil/runtimeContext.cpp | 38 | ||||
-rw-r--r-- | libadhocutil/runtimeContext.h | 28 | ||||
-rw-r--r-- | libadhocutil/unittests/Jamfile.jam | 19 | ||||
-rw-r--r-- | libadhocutil/unittests/testContext.cpp | 34 |
5 files changed, 121 insertions, 0 deletions
diff --git a/libadhocutil/Jamfile.jam b/libadhocutil/Jamfile.jam index 8169ad0..b689242 100644 --- a/libadhocutil/Jamfile.jam +++ b/libadhocutil/Jamfile.jam @@ -26,5 +26,7 @@ lib adhocutil : <include>. ; +build-project unittests ; + package.install install : <install-source-root>. : : adhocutil : [ glob *.h ] ; diff --git a/libadhocutil/runtimeContext.cpp b/libadhocutil/runtimeContext.cpp new file mode 100644 index 0000000..f4e12c2 --- /dev/null +++ b/libadhocutil/runtimeContext.cpp @@ -0,0 +1,38 @@ +#include "runtimeContext.h" +#include <stdexcept> + +RuntimeContext::RuntimeContext(size_t stacksize) : + swapped(false) +{ + stack = malloc(stacksize); + if (getcontext(&callback) == -1) + throw std::runtime_error("Failed to getcontext"); + callback.uc_stack.ss_sp = stack; + callback.uc_stack.ss_size = stacksize; + callback.uc_link = &initial; + makecontext(&callback, (void (*)())&RuntimeContext::ccallback, 1, this); +} + +RuntimeContext::~RuntimeContext() +{ + free(stack); +} + +void +RuntimeContext::SwapContext() +{ + swapped = !swapped; + if (swapped) { + swapcontext(&initial, &callback); + } + else { + swapcontext(&callback, &initial); + } +} + +void +RuntimeContext::ccallback(RuntimeContext * rc) +{ + rc->Callback(); +} + diff --git a/libadhocutil/runtimeContext.h b/libadhocutil/runtimeContext.h new file mode 100644 index 0000000..6fe26f0 --- /dev/null +++ b/libadhocutil/runtimeContext.h @@ -0,0 +1,28 @@ +#ifndef ADHOCUTIL_RUNTIMECONTEXT_H +#define ADHOCUTIL_RUNTIMECONTEXT_H + +#include <stdlib.h> +#include <ucontext.h> +#include "visibility.h" + +class DLL_PUBLIC RuntimeContext { + public: + RuntimeContext(size_t stacksize = 16384); + virtual ~RuntimeContext(); + + void SwapContext(); + + protected: + DLL_PRIVATE virtual void Callback() = 0; + + private: + DLL_PRIVATE static void ccallback(RuntimeContext * rc); + + void * stack; + ucontext_t initial; + ucontext_t callback; + bool swapped; +}; + +#endif + diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam new file mode 100644 index 0000000..65d8fad --- /dev/null +++ b/libadhocutil/unittests/Jamfile.jam @@ -0,0 +1,19 @@ +import testing ; + +path-constant me : . ; + +lib boost_utf : : <name>boost_unit_test_framework ; +lib boost_filesystem ; +lib boost_system ; + +run + testContext.cpp + : : : + <define>ROOT=\"$(me)\" + <define>BOOST_TEST_DYN_LINK + <library>..//adhocutil + <library>boost_utf + : + testContext + ; + diff --git a/libadhocutil/unittests/testContext.cpp b/libadhocutil/unittests/testContext.cpp new file mode 100644 index 0000000..6a291bf --- /dev/null +++ b/libadhocutil/unittests/testContext.cpp @@ -0,0 +1,34 @@ +#define BOOST_TEST_MODULE Context +#include <boost/test/unit_test.hpp> + +#include "runtimeContext.h" + +class testRuntimeContext : RuntimeContext { + public: + void Run() + { + log += "a"; + SwapContext(); + log += "b"; + SwapContext(); + log += "c"; + } + + void Callback() override + { + log += "d"; + SwapContext(); + log += "e"; + SwapContext(); + } + + std::string log; +}; + +BOOST_AUTO_TEST_CASE ( basic ) +{ + testRuntimeContext trc; + trc.Run(); + BOOST_REQUIRE_EQUAL("adbec", trc.log); +} + |