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); +} + | 
