diff --git a/example/cpp03/Jamfile.v2 b/example/cpp03/Jamfile.v2 index 519306b..ac23140 100644 --- a/example/cpp03/Jamfile.v2 +++ b/example/cpp03/Jamfile.v2 @@ -14,21 +14,6 @@ import modules ; import os ; import toolset ; -if [ os.name ] = SOLARIS -{ - lib socket ; - lib nsl ; -} -else if [ os.name ] = NT -{ - lib ws2_32 ; - lib mswsock ; -} -else if [ os.name ] = HPUX -{ - lib ipv6 ; -} - project boost/coroutine/example : requirements ../../build//boost_coroutine @@ -40,42 +25,6 @@ project boost/coroutine/example multi ; -exe segmented_stack - : segmented_stack.cpp - ; - -exe fibonacci - : fibonacci.cpp - ; - -exe echo - : echo.cpp - ; - -exe power - : power.cpp - ; - -exe parallel - : parallel.cpp - ; - -exe unwind - : unwind.cpp - ; - -exe same_fringe - : same_fringe.cpp - ; - -exe layout - : layout.cpp - ; - -exe chaining - : chaining.cpp - ; - -exe exception - : exception.cpp +exe simple + : simple.cpp ; diff --git a/example/cpp03/simple.cpp b/example/cpp03/simple.cpp new file mode 100644 index 0000000..2dcdd9a --- /dev/null +++ b/example/cpp03/simple.cpp @@ -0,0 +1,37 @@ + +// Copyright Oliver Kowalke 2009. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +#include +#include + +typedef boost::coroutines::coroutine< void >::pull_type pull_coro_t; +typedef boost::coroutines::coroutine< void >::push_type push_coro_t; + +void runit( push_coro_t & sink) +{ + std::cout << "started! "; + for ( int i = 0; i < 10; ++i) + { + sink(); + } +} + +int main( int argc, char * argv[]) +{ + { + pull_coro_t source( runit); + while ( source) { + source(); + } + } + + std::cout << "\nDone" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/include/boost/coroutine/coroutine.hpp b/include/boost/coroutine/coroutine.hpp index 6515b6f..f095ee1 100644 --- a/include/boost/coroutine/coroutine.hpp +++ b/include/boost/coroutine/coroutine.hpp @@ -1354,7 +1354,9 @@ private: struct dummy { void nonnull() {} }; - ptr_t impl_; + base_t * impl_; + stack_allocator stack_alloc_; + stack_context stack_ctx_; BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine) @@ -1480,19 +1482,26 @@ public: #else template< typename Fn > explicit pull_coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = stack_allocator(), std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >(), typename disable_if< is_convertible< Fn &, BOOST_RV_REF(Fn) >, dummy* >::type = 0) : - impl_() + impl_( 0), + stack_alloc_() + stack_ctx_(), { typedef detail::pull_coroutine_object< - void, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< void > + void, Fn, push_coroutine< void > > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + + stack_alloc_.alocate( stack_ctx_, attr.size); + detail::coroutine_context caller; + detail::coroutine_context callee( trampoline1_ex< Fn, object_t >, & stack_ctx_); + init< Fn, object_t > to( fn, & caller, & callee, & attr); + impl_ = reinterpret_cast< base_t >( + caller.jump( + callee, + reinterpret_cast< intptr_t >( & to), + fpu_preserved == attr.preserve_fpu) ); + BOOST_ASSERT( impl_); } template< typename Fn, typename StackAllocator > @@ -1588,7 +1597,7 @@ public: #endif pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT : - impl_() + impl_( 0) { swap( other); } pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT @@ -1607,7 +1616,7 @@ public: { return empty() || impl_->is_complete(); } void swap( pull_coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } + { std::swap( impl_, other.impl_); } pull_coroutine & operator()() { diff --git a/include/boost/coroutine/detail/trampoline.hpp b/include/boost/coroutine/detail/trampoline.hpp index 2c8088f..10d672c 100644 --- a/include/boost/coroutine/detail/trampoline.hpp +++ b/include/boost/coroutine/detail/trampoline.hpp @@ -22,6 +22,18 @@ namespace boost { namespace coroutines { namespace detail { +template< typename Fn, typename Coro > +void trampoline1_ex( intptr_t vp) +{ + BOOST_ASSERT( vp); + + init< Fn, Coro > * from( + reinterpret_cast< init< Fn, Coro > * >( vp); + + Coro c( from->fn, from->attr, from->caller, from->callee); + c.run(); +} + template< typename Coroutine > void trampoline1( intptr_t vp) {