$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: hartmut.kaiser_at_[hidden]
Date: 2007-11-28 12:20:21
Author: hkaiser
Date: 2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
New Revision: 41437
URL: http://svn.boost.org/trac/boost/changeset/41437
Log:
[Coroutine] Added support for Linux/gcc 64 Bit systems. Fixed a lot of typos in comments, untabified files.
Added:
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_linux64.hpp   (contents, props changed)
   sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext32.cpp   (contents, props changed)
   sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext64.cpp   (contents, props changed)
Text files modified: 
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/coroutine.hpp                   |    62 +++++++++---------                      
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_base.hpp         |     8 +-                                      
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_linux.hpp        |   131 ++++++++++++++++++++------------------- 
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_windows.hpp      |    76 +++++++++++-----------                  
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/coroutine_accessor.hpp   |     4                                         
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/coroutine_impl.hpp       |    57 ++++++++--------                        
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/default_context_impl.hpp |    27 ++++++-                                 
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/posix_utility.hpp        |     4                                         
   sandbox/SOC/2006/coroutine/trunk/boost/coroutine/shared_coroutine.hpp            |     2                                         
   sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext.cpp              |    95 ++--------------------------            
   10 files changed, 203 insertions(+), 263 deletions(-)
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/coroutine.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/coroutine.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/coroutine.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -54,8 +54,8 @@
     template<typename T>
     struct optional_result_type : 
       boost::mpl::if_<boost::is_same<T, void>,
-		      void,
-		      boost::optional<T> > { };
+                      void,
+                      boost::optional<T> > { };
 
     template<typename T>
     BOOST_DEDUCED_TYPENAME
@@ -65,12 +65,12 @@
     template<typename T>
     BOOST_DEDUCED_TYPENAME
     boost::disable_if<boost::is_same<T, void>,
-		      BOOST_DEDUCED_TYPENAME
-		      optional_result_type<T>::type
-		      >::type
+                      BOOST_DEDUCED_TYPENAME
+                      optional_result_type<T>::type
+                      >::type
     optional_result() {
       return BOOST_DEDUCED_TYPENAME
-	optional_result_type<T>::type();
+        optional_result_type<T>::type();
     }
   }
 
@@ -84,7 +84,7 @@
   struct is_coroutine<coroutine<Sig, Con> > : boost::mpl::true_{};
 
   template<typename Signature, 
-	   typename ContextImpl = detail::default_context_impl>
+           typename ContextImpl = detail::default_context_impl>
   class coroutine : public movable<coroutine<Signature, ContextImpl> > {
   public:
     typedef coroutine<Signature, ContextImpl> type;
@@ -124,14 +124,14 @@
 
     template<typename Functor>
     coroutine (Functor f, 
-	       std::ptrdiff_t stack_size = detail::default_stack_size,
-	       BOOST_DEDUCED_TYPENAME boost::enable_if<
-	       boost::mpl::and_<
-	       detail::is_callable<Functor>, 
-	       boost::mpl::not_<is_coroutine<Functor> >
-	       > >
-	       ::type * = 0
-	       ) :
+               std::ptrdiff_t stack_size = detail::default_stack_size,
+               BOOST_DEDUCED_TYPENAME boost::enable_if<
+               boost::mpl::and_<
+               detail::is_callable<Functor>, 
+               boost::mpl::not_<is_coroutine<Functor> >
+               > >
+               ::type * = 0
+               ) :
       m_pimpl(impl_type::create(f, stack_size)) {}
  
     coroutine(move_from<coroutine> src) 
@@ -160,15 +160,15 @@
     /**/
 
     BOOST_PP_REPEAT(BOOST_COROUTINE_ARG_MAX,
-		    BOOST_COROUTINE_generate_argument_n_type,
-		    arg_slot_traits);
+                    BOOST_COROUTINE_generate_argument_n_type,
+                    arg_slot_traits);
 
     static const int arity = arg_slot_traits::length;
 
     struct yield_traits {
       BOOST_PP_REPEAT(BOOST_COROUTINE_ARG_MAX,
-		      BOOST_COROUTINE_generate_argument_n_type,
-		      result_slot_traits);
+                      BOOST_COROUTINE_generate_argument_n_type,
+                      result_slot_traits);
       static const int arity = result_slot_traits::length;
     };
 
@@ -184,12 +184,12 @@
     result_type operator()
       (BOOST_PP_ENUM
        (BOOST_COROUTINE_ARG_MAX,
-	BOOST_COROUTINE_param_with_default,
-	arg)) {
+        BOOST_COROUTINE_param_with_default,
+        arg)) {
       return call_impl
-	(arg_slot_type(BOOST_PP_ENUM_PARAMS
-	  (BOOST_COROUTINE_ARG_MAX, 
-	   arg)));
+        (arg_slot_type(BOOST_PP_ENUM_PARAMS
+          (BOOST_COROUTINE_ARG_MAX, 
+           arg)));
     }
 
     BOOST_DEDUCED_TYPENAME
@@ -198,12 +198,12 @@
       (const std::nothrow_t&
        BOOST_PP_ENUM_TRAILING
        (BOOST_COROUTINE_ARG_MAX,
-	BOOST_COROUTINE_param_with_default,
-	arg)) {
+        BOOST_COROUTINE_param_with_default,
+        arg)) {
       return call_impl_nothrow
-	(arg_slot_type(BOOST_PP_ENUM_PARAMS
-	  (BOOST_COROUTINE_ARG_MAX, 
-	   arg)));
+        (arg_slot_type(BOOST_PP_ENUM_PARAMS
+          (BOOST_COROUTINE_ARG_MAX, 
+           arg)));
     }
 
 #   undef BOOST_COROUTINE_param_typedef
@@ -244,7 +244,7 @@
   protected:
 
     // The second parameter is used to avoid calling this constructor
-    // by mistake from other member funcitons (specifically operator=).
+    // by mistake from other member functions (specifically operator=).
     coroutine(impl_type * pimpl, detail::init_from_impl_tag) :
       m_pimpl(pimpl) {}
 
@@ -272,7 +272,7 @@
       result_slot_type * ptr;
       m_pimpl->bind_result_pointer(&ptr);
       if(!m_pimpl->wake_up())
-	return detail::optional_result<result_type>();
+        return detail::optional_result<result_type>();
 
       return detail::fix_result<result_slot_traits>(*m_pimpl->result());
     }
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_base.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_base.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_base.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -205,7 +205,7 @@
     void invoke() {
       BOOST_ASSERT(ready());
       do_invoke();
-      // TODO: could use a bynary or here to eliminate
+      // TODO: could use a binary or here to eliminate
       // shortcut evaluation (and a branch), but maybe the compiler is
       // smart enough to do it anyway as there are no side effects.
       if(m_exit_status || m_state == ctx_waiting) {
@@ -220,7 +220,7 @@
         } else if(m_exit_status == ctx_exited_exit)
           throw coroutine_exited();
               else {
-	  BOOST_ASSERT(0 && "unkonw exit status");
+	  BOOST_ASSERT(0 && "unknown exit status");
         }
       }
     }
@@ -263,7 +263,7 @@
     // The exit_exception would cause the future to be destroyed and
     // an assertion to be generated. Removing an assertion is not a 
     // solution because we would leak the coroutine impl. The callback
-    // bound to the future in fact hold a refrence to it. If the coroutine
+    // bound to the future in fact hold a reference to it. If the coroutine
     // is exited the callback cannot be called.
     void wait(int n) {
       BOOST_ASSERT(!(n<0));
@@ -300,7 +300,7 @@
     // Cause this coroutine to exit.
     // Can only be called on a ready coroutine.
     // Cannot be called if there are pending operations.
-    // It follws that cannot be called from 'this'.
+    // It follows that cannot be called from 'this'.
     // Nothrow.
     void exit() throw(){
       BOOST_ASSERT(!pending());
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_linux.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_linux.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_linux.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -37,7 +37,7 @@
 
 /*
  * Defining BOOST_COROUTINE_INLINE_ASM will enable the inlin3
- * assembler verwsion of swapcontext_stack.
+ * assembler version of swapcontext_stack.
  * The inline asm, with all required clobber flags, is usually no faster
  * than the out-of-line function, and it is not yet clear if
  * it is always reliable (i.e. if the compiler always saves the correct
@@ -109,26 +109,26 @@
 fun_type get_swapper(){
   fun_type ptr;
   asm volatile("mov $0f, %[result]"
-	       "\n\t jmp 1f"
-	       "\n0:"
-	       //"\n\t movl 16(%%edx), %%ecx"
-	       "\n\t pushl %%ebp"
-	       "\n\t pushl %%ebx"
-	       "\n\t pushl %%esi"
-	       "\n\t pushl %%edi"
-	       "\n\t movl %%esp, (%%eax)"
-	       "\n\t movl %%edx, %%esp"
-	       "\n\t popl %%edi"
-	       "\n\t popl %%esi"
-	       "\n\t popl %%ebx"
-	       "\n\t popl %%ebp"
-	       "\n\t popl %%ecx"
-	       "\n\t jmp *%%ecx"
-	       "\n1:"
-	       :
-	       [result] "=g" (ptr) 
-	       :       
-	       );
+               "\n\t jmp 1f"
+               "\n0:"
+               //"\n\t movl 16(%%edx), %%ecx"
+               "\n\t pushl %%ebp"
+               "\n\t pushl %%ebx"
+               "\n\t pushl %%esi"
+               "\n\t pushl %%edi"
+               "\n\t movl %%esp, (%%eax)"
+               "\n\t movl %%edx, %%esp"
+               "\n\t popl %%edi"
+               "\n\t popl %%esi"
+               "\n\t popl %%ebx"
+               "\n\t popl %%ebp"
+               "\n\t popl %%ecx"
+               "\n\t jmp *%%ecx"
+               "\n1:"
+               :
+               [result] "=g" (ptr) 
+               :       
+               );
   return ptr;
 };
 
@@ -167,16 +167,16 @@
       ia32_gcc_context_impl_base() {};
 
       void prefetch() const {
-	__builtin_prefetch (m_sp, 1, 3);
-	__builtin_prefetch (m_sp, 0, 3);
-	__builtin_prefetch ((void**)m_sp+64/4, 1, 3);
-	__builtin_prefetch ((void**)m_sp+64/4, 0, 3);
-	__builtin_prefetch ((void**)m_sp+32/4, 1, 3);
-	__builtin_prefetch ((void**)m_sp+32/4, 0, 3);
-	__builtin_prefetch ((void**)m_sp-32/4, 1, 3);
-	__builtin_prefetch ((void**)m_sp-32/4, 0, 3);
-	__builtin_prefetch ((void**)m_sp-64/4, 1, 3);
-	__builtin_prefetch ((void**)m_sp-64/4, 0, 3);
+        __builtin_prefetch (m_sp, 1, 3);
+        __builtin_prefetch (m_sp, 0, 3);
+        __builtin_prefetch ((void**)m_sp+64/4, 1, 3);
+        __builtin_prefetch ((void**)m_sp+64/4, 0, 3);
+        __builtin_prefetch ((void**)m_sp+32/4, 1, 3);
+        __builtin_prefetch ((void**)m_sp+32/4, 0, 3);
+        __builtin_prefetch ((void**)m_sp-32/4, 1, 3);
+        __builtin_prefetch ((void**)m_sp-32/4, 0, 3);
+        __builtin_prefetch ((void**)m_sp-64/4, 1, 3);
+        __builtin_prefetch ((void**)m_sp-64/4, 0, 3);
       }
 
       /**
@@ -187,29 +187,29 @@
       friend 
       void 
       swap_context(ia32_gcc_context_impl_base& from, 
-		   ia32_gcc_context_impl_base const& to, 
-		   default_hint) {
-	to.prefetch();
-	swapcontext_stack(&from.m_sp, to.m_sp);
+                   ia32_gcc_context_impl_base const& to, 
+                   default_hint) {
+        to.prefetch();
+        swapcontext_stack(&from.m_sp, to.m_sp);
       }
 
 #ifndef BOOST_COROUTINE_NO_SEPARATE_CALL_SITES
       friend 
       void 
       swap_context(ia32_gcc_context_impl_base& from, 
-		   ia32_gcc_context_impl_base const& to,
-		   yield_hint) {
-	to.prefetch();
-	swapcontext_stack2(&from.m_sp, to.m_sp);
+                   ia32_gcc_context_impl_base const& to,
+                   yield_hint) {
+        to.prefetch();
+        swapcontext_stack2(&from.m_sp, to.m_sp);
       }
 
       friend 
       void 
       swap_context(ia32_gcc_context_impl_base& from, 
-		   ia32_gcc_context_impl_base const& to,
-		   yield_to_hint) {
-	to.prefetch();
-	swapcontext_stack2(&from.m_sp, to.m_sp);
+                   ia32_gcc_context_impl_base const& to,
+                   yield_to_hint) {
+        to.prefetch();
+        swapcontext_stack2(&from.m_sp, to.m_sp);
       }
 
 #endif
@@ -226,41 +226,42 @@
       typedef ia32_gcc_context_impl_base context_impl_base;
 
       ia32_gcc_context_impl() :
-	m_stack(0) {}
+        m_stack(0) {}
       /**
        * Create a context that on restore invokes Functor on
        *  a new stack. The stack size can be optionally specified.
        */
       template<typename Functor>
-	  ia32_gcc_context_impl(Functor& cb, std::ptrdiff_t stack_size = -1) :
-	m_stack_size(stack_size == -1? default_stack_size: stack_size),
-	m_stack(posix::alloc_stack(m_stack_size)) {
-	m_sp = ((void**)m_stack + (m_stack_size/sizeof(void*))),
-	BOOST_ASSERT(m_stack);
-	typedef void fun(Functor*);
-	fun * funp = trampoline;
+          ia32_gcc_context_impl(Functor& cb, std::ptrdiff_t stack_size = -1) :
+        m_stack_size(stack_size == -1? default_stack_size: stack_size),
+        m_stack(posix::alloc_stack(m_stack_size)) 
+      {
+        m_sp = ((void**)m_stack + (m_stack_size/sizeof(void*)));
+        BOOST_ASSERT(m_stack);
+        typedef void fun(Functor*);
+        fun * funp = trampoline;
 #ifndef BOOST_COROUTINE_INLINE_ASM
-	*--m_sp = &cb;     // parm 0 of trampoline;
-	*--m_sp = 0;        // dummy return address for trampoline
-	*--m_sp = (void*) funp ;// return addr (here: start addr)  NOTE: the unsafe cast is safe on IA32
-	*--m_sp = 0;       // ebp                                  
-	*--m_sp = 0;       // ebx                                  
-	*--m_sp = 0;       // esi                                  
-	*--m_sp = 0;       // edi        
+        *--m_sp = &cb;     // parm 0 of trampoline;
+        *--m_sp = 0;        // dummy return address for trampoline
+        *--m_sp = (void*) funp ;// return addr (here: start addr)  NOTE: the unsafe cast is safe on IA32
+        *--m_sp = 0;       // ebp                                  
+        *--m_sp = 0;       // ebx                                  
+        *--m_sp = 0;       // esi                                  
+        *--m_sp = 0;       // edi        
 #else
-	*--m_sp = &cb;     // parm 0 of trampoline;
-	*--m_sp = 0;        // dummy return address for trampoline
-	*--m_sp = (void*) funp ;// return addr (here: start addr)  NOTE: the unsafe cast is safe on IA32
+        *--m_sp = &cb;     // parm 0 of trampoline;
+        *--m_sp = 0;        // dummy return address for trampoline
+        *--m_sp = (void*) funp ;// return addr (here: start addr)  NOTE: the unsafe cast is safe on IA32
 #endif
       }
       
       ~ia32_gcc_context_impl() {
-	if(m_stack)
-	  posix::free_stack(m_stack, m_stack_size);
+        if(m_stack)
+          posix::free_stack(m_stack, m_stack_size);
       }
 
     private:
-	  std::ptrdiff_t m_stack_size;
+          std::ptrdiff_t m_stack_size;
       void * m_stack;
     };
     
@@ -269,6 +270,7 @@
 } } }
 
 #elif defined(__linux)
+
 /**
  * For all other linux systems use the standard posix implementation.
  */
@@ -276,6 +278,7 @@
 namespace boost { namespace coroutines { namespace detail { namespace oslinux {
     typedef posix::context_impl context_impl;
 } } } }
+
 #else
 #error This header can only be included when compiling for linux systems.
 #endif
Added: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_linux64.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_linux64.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -0,0 +1,167 @@
+//  Copyright (c) 2007 Robert Perricone
+//  Copyright (c) 2007 Hartmut Kaiser
+//
+//  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)
+
+#ifndef BOOST_COROUTINE_CONTEXT_LINUX_HPP_20071126
+#define BOOST_COROUTINE_CONTEXT_LINUX_HPP_20071126
+
+#if defined(__GNUC__) && defined(__x86_64__) && !defined(BOOST_COROUTINE_NO_ASM)
+#include <cstdlib>
+#include <cstddef>
+#include <boost/coroutine/detail/posix_utility.hpp>
+#include <boost/coroutine/detail/swap_context.hpp>
+
+/* 
+ * Defining BOOST_COROUTINE_NO_SEPARATE_CALL_SITES will disable separate 
+ * invoke, yield and yield_to swap_context functions. Separate calls sites
+ * increase performance by 25% at least on P4 for invoke+yield back loops
+ * at the cost of a slightly higher instruction cache use and is thus enabled by
+ * default.
+ */
+//#define BOOST_COROUTINE_NO_SEPARATE_CALL_SITES
+
+extern "C" void swapcontext_stack (void***, void**) throw();
+extern "C" void swapcontext_stack2 (void***, void**) throw();
+extern "C" void swapcontext_stack3 (void***, void**) throw();
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace coroutines { namespace detail {
+  namespace oslinux64 
+  {
+    template<typename T>
+    void trampoline(T* fun);
+    
+    template<typename T>
+    inline void
+    trampoline(T* fun) 
+    { 
+      (*fun)();
+      std::abort();
+    }
+
+    class ia64_gcc_context_impl_base 
+    {
+    public:
+      ia64_gcc_context_impl_base() {}
+
+      void prefetch() const 
+      {
+        __builtin_prefetch (m_sp, 1, 3);
+        __builtin_prefetch (m_sp, 0, 3);
+        __builtin_prefetch ((void**)m_sp+64/8, 1, 3);
+        __builtin_prefetch ((void**)m_sp+64/8, 0, 3);
+        __builtin_prefetch ((void**)m_sp+32/8, 1, 3);
+        __builtin_prefetch ((void**)m_sp+32/8, 0, 3);
+        __builtin_prefetch ((void**)m_sp-32/8, 1, 3);
+        __builtin_prefetch ((void**)m_sp-32/8, 0, 3);
+        __builtin_prefetch ((void**)m_sp-64/8, 1, 3);
+        __builtin_prefetch ((void**)m_sp-64/8, 0, 3);
+      }
+
+      /**
+       * Free function. Saves the current context in @p from
+       * and restores the context in @p to.
+       * @note This function is found by ADL.
+       */     
+      friend void 
+      swap_context(ia64_gcc_context_impl_base& from, 
+                   ia64_gcc_context_impl_base const& to, 
+                   default_hint) 
+      {
+        to.prefetch();
+        swapcontext_stack(&from.m_sp, to.m_sp);
+      }
+
+#ifndef BOOST_COROUTINE_NO_SEPARATE_CALL_SITES
+      friend void 
+      swap_context(ia64_gcc_context_impl_base& from, 
+                   ia64_gcc_context_impl_base const& to,
+                   yield_hint) 
+      {
+        to.prefetch();
+        swapcontext_stack2(&from.m_sp, to.m_sp);
+      }
+
+      friend void 
+      swap_context(ia64_gcc_context_impl_base& from, 
+                   ia64_gcc_context_impl_base const& to,
+                   yield_to_hint) 
+      {
+        to.prefetch();
+        swapcontext_stack3(&from.m_sp, to.m_sp);
+      }
+#endif
+
+    protected:
+      void ** m_sp;
+    };
+
+    class ia64_gcc_context_impl : public ia64_gcc_context_impl_base
+    {
+    public:
+      enum { default_stack_size = 8192 };
+      
+      typedef ia64_gcc_context_impl_base context_impl_base;
+
+      ia64_gcc_context_impl() :
+        m_stack(0) {}
+        
+      /**
+       * Create a context that on restore invokes Functor on
+       *  a new stack. The stack size can be optionally specified.
+       */
+      template<typename Functor>
+      ia64_gcc_context_impl(Functor& cb, std::ptrdiff_t stack_size = -1) 
+        : m_stack_size(stack_size == -1 ? default_stack_size : stack_size),
+          m_stack(posix::alloc_stack(m_stack_size)) 
+      {
+        BOOST_ASSERT(m_stack);
+        m_sp = ((void**)m_stack + (m_stack_size/sizeof(void*)));
+        
+        typedef void fun(Functor*);
+        fun * funp = trampoline;
+
+        *--m_sp = &cb;     // parm 0 of trampoline;
+        *--m_sp = 0;       // dummy return address for trampoline
+        *--m_sp = (void*) funp ;// return addr (here: start addr)  NOTE: the unsafe cast is safe on IA64
+        *--m_sp = 0;       // rbp                                  
+        *--m_sp = 0;       // rbx                                  
+        *--m_sp = 0;       // rsi                                  
+        *--m_sp = 0;       // rdi        
+      }
+      
+      ~ia64_gcc_context_impl() 
+      {
+        if(m_stack)
+          posix::free_stack(m_stack, m_stack_size);
+      }
+
+    private:
+      std::ptrdiff_t m_stack_size;
+      void * m_stack;
+    };
+    
+    typedef ia64_gcc_context_impl context_impl;
+  }
+}}}
+
+#elif defined(__linux)
+/**
+ * For all other linux systems use the standard posix implementation.
+ */
+#include <boost/coroutine/detail/context_posix.hpp>
+namespace boost { namespace coroutines { namespace detail { 
+  namespace oslinux64 
+  {
+    typedef posix::context_impl context_impl;
+  } 
+}}}
+#else
+#error This header can only be included when compiling for linux systems.
+#endif
+
+#endif
+
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_windows.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_windows.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/context_windows.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -42,17 +42,17 @@
 
     /*
      * This number (0x1E00) has been sighted in the wild (at least on windows XP systems)
-     * as return value from GetCurrentFiber() on non fibrous threads. This is sowehow related
+     * as return value from GetCurrentFiber() on non fibrous threads. This is somehow related
      * to OS/2 where the current fiber pointer is overloaded as a version field.
      * On non-NT systems, 0 is returned. 
      */
-    fiber_ptr fiber_magic = reinterpret_cast<fiber_ptr>(0x1E00);
-		
+    fiber_ptr const fiber_magic = reinterpret_cast<fiber_ptr>(0x1E00);
+                
     /*
      * Return true if current thread is a fiber.
-     * FIXME: on longhorn shoud use IsThreadAFiber
+     * FIXME: on longhorn should use IsThreadAFiber
      */
-    bool is_fiber() {
+    inline bool is_fiber() {
       fiber_ptr current = GetCurrentFiber();
       return current != 0 && current != fiber_magic;
     }
@@ -71,8 +71,8 @@
        * but can be saved in.
        */
       fibers_context_impl_base() :
-	m_ctx(0) {}
-	
+        m_ctx(0) {}
+        
       /*
        * Free function. Saves the current context in @p from
        * and restores the context in @p to. On windows the from
@@ -89,34 +89,34 @@
       friend 
       void 
       swap_context(fibers_context_impl_base& from, 
-		   const fibers_context_impl_base& to,
-		   default_hint) {
-	if(!is_fiber()) {
-	  BOOST_ASSERT(from.m_ctx == 0);
-	  from.m_ctx = ConvertThreadToFiber(0);
-	  BOOST_ASSERT(from.m_ctx != 0);
-	  
-	  SwitchToFiber(to.m_ctx); 
-	  
-	  BOOL result = ConvertFiberToThread();
-	  BOOST_ASSERT(result);
-	  (void)result;
-	  from.m_ctx = 0;
-	} else {
-	  bool call_from_main = from.m_ctx == 0;
-	  if(call_from_main)
-	    from.m_ctx = GetCurrentFiber();
-	  SwitchToFiber(to.m_ctx); 
-	  if(call_from_main)
-	    from.m_ctx = 0;
-	}
+                   const fibers_context_impl_base& to,
+                   default_hint) {
+        if(!is_fiber()) {
+          BOOST_ASSERT(from.m_ctx == 0);
+          from.m_ctx = ConvertThreadToFiber(0);
+          BOOST_ASSERT(from.m_ctx != 0);
+          
+          SwitchToFiber(to.m_ctx); 
+          
+          BOOL result = ConvertFiberToThread();
+          BOOST_ASSERT(result);
+          (void)result;
+          from.m_ctx = 0;
+        } else {
+          bool call_from_main = from.m_ctx == 0;
+          if(call_from_main)
+            from.m_ctx = GetCurrentFiber();
+          SwitchToFiber(to.m_ctx); 
+          if(call_from_main)
+            from.m_ctx = 0;
+        }
       }
 
       ~fibers_context_impl_base() {}
     protected:
       explicit
       fibers_context_impl_base(fiber_ptr ctx) :
-	m_ctx(ctx) {}
+        m_ctx(ctx) {}
 
       fiber_ptr m_ctx;
     };
@@ -139,24 +139,24 @@
       enum {default_stack_size = 8192};
 
       /**
-       * Create a context that on restore inovkes Functor on
+       * Create a context that on restore invokes Functor on
        *  a new stack. The stack size can be optionally specified.
        */
       template<typename Functor>
       explicit
       fibers_context_impl(Functor& cb, std::ptrdiff_t stack_size) :
-	fibers_context_impl_base
-      (CreateFiber(stack_size== -1? 0 : stack_size,
-		   static_cast<LPFIBER_START_ROUTINE>(&trampoline<Functor>),
-		   static_cast<LPVOID>(&cb)))
+        fibers_context_impl_base
+      (CreateFiber(stack_size== -1? default_stack_size : stack_size,
+                   static_cast<LPFIBER_START_ROUTINE>(&trampoline<Functor>),
+                   static_cast<LPVOID>(&cb)))
       {
-	BOOST_ASSERT(m_ctx);
+        BOOST_ASSERT(m_ctx);
       }
-		  
+                  
       ~fibers_context_impl() {
-	DeleteFiber(m_ctx);
+        DeleteFiber(m_ctx);
       }
-		  
+                  
     private:
     };
 
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/coroutine_accessor.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/coroutine_accessor.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/coroutine_accessor.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -62,11 +62,11 @@
     struct in_place_assign : boost::in_place_factory_base {
 
       in_place_assign(Ctx * ctx) :
-	m_ctx(ctx) {}
+        m_ctx(ctx) {}
 
       template<typename Coroutine>
       void apply(void * memory) const {
-	construct<Coroutine>(m_ctx, memory);
+        construct<Coroutine>(m_ctx, memory);
       }
       Ctx * m_ctx;
     };
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/coroutine_impl.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/coroutine_impl.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/coroutine_impl.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -40,7 +40,7 @@
 #include <boost/coroutine/detail/context_base.hpp>
 
 namespace boost { namespace coroutines { namespace detail {
-	
+        
   // This class augment the contest_base class with
   // the coroutine signature type.
   // This is mostly just a place to put
@@ -64,10 +64,10 @@
     typedef boost::intrusive_ptr<type> pointer;
   
     template<typename DerivedType>
-	coroutine_impl(DerivedType * this_, std::ptrdiff_t stack_size) :
+        coroutine_impl(DerivedType * this_, std::ptrdiff_t stack_size) :
       context_base(*this_, stack_size),
-	m_arg(0),
-	m_result(0){}
+        m_arg(0),
+        m_result(0){}
                 
     arg_slot_type * args() {
       BOOST_ASSERT(m_arg);
@@ -81,8 +81,8 @@
     } 
 
     template<typename Functor>
-	static inline	
-	pointer create(Functor, std::ptrdiff_t);
+        static inline	
+        pointer create(Functor, std::ptrdiff_t);
 
     void bind_args(arg_slot_type* arg) {
       m_arg = arg;
@@ -92,7 +92,7 @@
       *m_result = res;
     }
 
-    // Another level of indirecition is needed to handle
+    // Another level of indirection is needed to handle
     // yield_to correctly.
     void bind_result_pointer(result_slot_type** resp) {
       m_result = resp;
@@ -141,26 +141,25 @@
     typedef coroutine_impl<CoroutineType, ContextImpl> super_type;
 
     typedef FunctorType functor_type;
-	coroutine_impl_wrapper(functor_type f, std::ptrdiff_t stack_size) :
-
-		super_type(this, stack_size),
+        coroutine_impl_wrapper(functor_type f, std::ptrdiff_t stack_size) :
+                super_type(this, stack_size),
       m_fun(f){}
 
     void operator()() {
       typedef typename super_type::context_exit_status
-	context_exit_status;
+        context_exit_status;
       context_exit_status status = super_type::ctx_exited_return;
       std::type_info const* tinfo = 0;
       try {
-	this->check_exit_state();
-	do_call<result_type>();
+        this->check_exit_state();
+        do_call<result_type>();
       } catch (const exit_exception&) {
-	status = super_type::ctx_exited_exit;
+        status = super_type::ctx_exited_exit;
       } catch (std::exception const& e) {
-	status = super_type::ctx_exited_abnormally;
-	tinfo = &typeid(e);
+        status = super_type::ctx_exited_abnormally;
+        tinfo = &typeid(e);
       } catch (...) {
-	status = super_type::ctx_exited_abnormally;
+        status = super_type::ctx_exited_abnormally;
       }
       this->do_return(status, tinfo);	  
     }
@@ -178,16 +177,16 @@
     do_call(dummy<0> = 0) {
       BOOST_ASSERT(this->count() > 0);
       typedef BOOST_DEDUCED_TYPENAME
-	coroutine_type::self self_type;
+        coroutine_type::self self_type;
       boost::optional<self_type> self (coroutine_accessor::in_place(this));
       detail::unpack_ex
-	(m_fun, 
-	 *self, 
-	 *this->args(), 
-	 detail::trait_tag<typename coroutine_type::arg_slot_traits>());
+        (m_fun, 
+         *self, 
+         *this->args(), 
+         detail::trait_tag<typename coroutine_type::arg_slot_traits>());
 
       typedef BOOST_DEDUCED_TYPENAME coroutine_type::result_slot_type 
-	result_slot_type;
+        result_slot_type;
 
       // In this particulare case result_slot_type is guaranteed to be
       // default constructible.
@@ -207,13 +206,13 @@
 
       typedef BOOST_DEDUCED_TYPENAME coroutine_type::arg_slot_traits traits;
       typedef BOOST_DEDUCED_TYPENAME coroutine_type::result_slot_type 
-	result_slot_type;
-	  
+        result_slot_type;
+          
       this->m_result_last = boost::in_place(result_slot_type(detail::unpack_ex
-			   (m_fun, 
-			    *self, 
-			    *this->args(), 
-			    detail::trait_tag<traits>())));      
+                           (m_fun, 
+                            *self, 
+                            *this->args(), 
+                            detail::trait_tag<traits>())));      
       
       this->bind_result(&*this->m_result_last);
     }
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/default_context_impl.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/default_context_impl.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/default_context_impl.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -61,7 +61,7 @@
      context_impl_base must have conform to the ContextImplBase concept:
        
      - DefaultConstructible. A default constructed ContextImplBase is in
-       an unitialized state. 
+       an initialized state. 
        A ContextImpl is an initialized ContextImplBase.
 
      - ContextImplBase is Copyable. A copy of a ContextImplBase holds
@@ -81,33 +81,48 @@
        Postconditions:
        The current context is saved in the 'from' context, and the
        'to' context is restored. 
-       It is undefined behaviour if the 'to' argument is an invalid 
-       (uninitialized) swapcontext.
+       It is undefined behavior if the 'to' argument is an invalid 
+       (uninitialized) swap context.
            
      A ContextImplBase is meant to be used when an empty temporary
      context is needed to store the current context before
      restoring a ContextImpl and no current context is
      available. It could be possible to simply have ContextImpl
-     default constructible, but on destruciton it would need to
+     default constructible, but on destruction it would need to
      check if a stack has been allocated and would slow down the
-     fast invcation path. Also a stackful context could not be
-     make copiable.
+     fast invocation path. Also a stack-full context could not be
+     make copyable.
 */
 
 #if defined(__linux) || defined(linux) || defined(__linux__)
 
+#if defined(__x86_64__)
+// 64 bit systems, use appropriate context switching
+
+#include <boost/coroutine/detail/context_linux64.hpp>
+namespace boost { namespace coroutines { namespace detail {
+  typedef oslinux64::context_impl default_context_impl;
+} } }
+
+#else
+// use 32 bit context switching
+
 #include <boost/coroutine/detail/context_linux.hpp>
 namespace boost { namespace coroutines { namespace detail {
   typedef oslinux::context_impl default_context_impl;
 } } }
 
+#endif
+
 #elif defined(_POSIX_VERSION)
 
 #include <boost/coroutine/detail/context_posix.hpp>
 namespace boost { namespace coroutines { namespace detail {
   typedef posix::context_impl default_context_impl;
 } } }
+
 #elif defined(BOOST_WINDOWS)
+
 #include <boost/coroutine/detail/context_windows.hpp>
 namespace boost { namespace coroutines { namespace detail {
   typedef windows::context_impl default_context_impl;
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/posix_utility.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/posix_utility.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/detail/posix_utility.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -58,9 +58,9 @@
    * Better implementations are possible using
    * mmap (might be required on some systems) and/or
    * using a pooling allocator.
-   * NOTE: the SuSv3 documentation explictly allows
+   * NOTE: the SuSv3 documentation explicitly allows
    * the use of malloc to allocate stacks for makectx.
-   * We use free for guaranteed alignment.
+   * We use new/delete for guaranteed alignment.
    */
   inline
   void* alloc_stack(std::size_t size) {
Modified: sandbox/SOC/2006/coroutine/trunk/boost/coroutine/shared_coroutine.hpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/boost/coroutine/shared_coroutine.hpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/boost/coroutine/shared_coroutine.hpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -31,7 +31,7 @@
 #include <boost/coroutine/coroutine.hpp>
 namespace boost { namespace coroutines {
   // This class is a workaround for the widespread lack of move
-  // semantics support. It is a refrence counted wrapper around 
+  // semantics support. It is a reference counted wrapper around 
   // the coroutine object.
   // FIXME: ATM a shared_coroutine is-a coroutine. This is to avoid
   // inheriting privately and cluttering the code with lots of using
Modified: sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext.cpp
==============================================================================
--- sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext.cpp	(original)
+++ sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext.cpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -1,95 +1,18 @@
-//  Copyright (c) 2006, Giovanni P. Deretta
-//
-//  This code may be used under either of the following two licences:
-//
-//  Permission is hereby granted, free of charge, to any person obtaining a copy 
-//  of this software and associated documentation files (the "Software"), to deal 
-//  in the Software without restriction, including without limitation the rights 
-//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
-//  copies of the Software, and to permit persons to whom the Software is 
-//  furnished to do so, subject to the following conditions:
-//
-//  The above copyright notice and this permission notice shall be included in 
-//  all copies or substantial portions of the Software.
-//
-//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
-//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
-//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
-//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
-//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
-//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
-//  THE SOFTWARE. OF SUCH DAMAGE.
-//
-//  Or:
+//  Copyright (c) 2007 Hartmut Kaiser
 //
 //  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)
 
-
-#if !defined(i386)
-#error This file is for x86 CPUs only.
-#endif
-
 #if !defined(__GNUC__)
-#error This file requires gcc.
+#error This file requires compilation using gcc.
 #endif
 
-/*
- * This file should really be a plain assembler file.
- * Unfortunately Boost.Build v2 doesn't handle asm files (yet).
- * For now resort to inline asm.
- */
-
-
-/* 
-   EAX is &from.sp	
-   EDX is to.sp
-   This is the simplest version of swapcontext
-   It saves registers on the old stack,
-   saves the old stack pointer, 
-   load the new stack pointer,
-   pop registers from the new stack
-   and returns to new caller.
-   EAX is simpy passed to the function it returns to.
-   The first time EAX is the first parameter of the trampoline.
-   Otherwise it is simply discarded.
-   NOTE: This function should work on any IA32 CPU.
-   NOTE: The biggest penality is the last jump that
-   will be always mispredicted (~50 cycles on P4).
-   We try to make its address available as soon as possible
-   to try to reduce the penality. Doing a ret instead of a 
-   'add $4, %esp'
-   'jmp *%ecx'
-   really kills performance.
-   NOTE: popl is slightly better than mov+add to pop registers
-   so is pushl rather than mov+sub.
-   */
-#define BOOST_COROUTINE_swapcontext(name) \
-asm volatile (                            \
-".text \n\t"                              \
-".global " #name "\n\t"                   \
-".type " #name "@function\n\t"            \
-".align 16\n\t"                           \
-#name":\n\t"                              \
-"movl  16(%edx), %ecx\n\t"                \
-"pushl %ebp\n\t"                          \
-"pushl %ebx\n\t"                          \
-"pushl %esi\n\t"                          \
-"pushl %edi\n\t"                          \
-"movl  %esp, (%eax)\n\t"                  \
-"movl  %edx, %esp\n\r"                    \
-"popl  %edi\n\t"                          \
-"popl  %esi\n\t"                          \
-"popl  %ebx\n\t"                          \
-"popl  %ebp\n\t"                          \
-"add   $4, %esp\n\t"                      \
-"jmp   *%ecx\n\t"                         \
-"ud2\n\t")                                \
-/**/
-
-BOOST_COROUTINE_swapcontext(swapcontext_stack);
-BOOST_COROUTINE_swapcontext(swapcontext_stack2);
-BOOST_COROUTINE_swapcontext(swapcontext_stack3);
+#if defined(__i386__)
+#include "swapcontext32.cpp"
+#elif defined(__x86_64__)
+#include "swapcontext64.cpp"
+#else
+#error Undefined platform (should be __386__ or __x86_64__)
+#endif
 
-#undef BOOST_COROUTINE_swapcontext
Added: sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext32.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext32.cpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -0,0 +1,95 @@
+//  Copyright (c) 2006, Giovanni P. Deretta
+//
+//  This code may be used under either of the following two licences:
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy 
+//  of this software and associated documentation files (the "Software"), to deal 
+//  in the Software without restriction, including without limitation the rights 
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+//  copies of the Software, and to permit persons to whom the Software is 
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in 
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
+//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
+//  THE SOFTWARE. OF SUCH DAMAGE.
+//
+//  Or:
+//
+//  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)
+
+
+#if !defined(i386)
+#error This file is for x86 CPUs only.
+#endif
+
+#if !defined(__GNUC__)
+#error This file requires gcc.
+#endif
+
+/*
+ * This file should really be a plain assembler file.
+ * Unfortunately Boost.Build v2 doesn't handle asm files (yet).
+ * For now resort to inline asm.
+ */
+
+
+/* 
+   EAX is &from.sp	
+   EDX is to.sp
+   This is the simplest version of swapcontext
+   It saves registers on the old stack,
+   saves the old stack pointer, 
+   load the new stack pointer,
+   pop registers from the new stack
+   and returns to new caller.
+   EAX is simpy passed to the function it returns to.
+   The first time EAX is the first parameter of the trampoline.
+   Otherwise it is simply discarded.
+   NOTE: This function should work on any IA32 CPU.
+   NOTE: The biggest penality is the last jump that
+   will be always mispredicted (~50 cycles on P4).
+   We try to make its address available as soon as possible
+   to try to reduce the penality. Doing a ret instead of a 
+   'add $4, %esp'
+   'jmp *%ecx'
+   really kills performance.
+   NOTE: popl is slightly better than mov+add to pop registers
+   so is pushl rather than mov+sub.
+   */
+#define BOOST_COROUTINE_swapcontext(name) \
+asm volatile (                            \
+".text \n\t"                              \
+".global " #name "\n\t"                   \
+".type " #name "@function\n\t"            \
+".align 16\n\t"                           \
+#name":\n\t"                              \
+"movl  16(%edx), %ecx\n\t"                \
+"pushl %ebp\n\t"                          \
+"pushl %ebx\n\t"                          \
+"pushl %esi\n\t"                          \
+"pushl %edi\n\t"                          \
+"movl  %esp, (%eax)\n\t"                  \
+"movl  %edx, %esp\n\r"                    \
+"popl  %edi\n\t"                          \
+"popl  %esi\n\t"                          \
+"popl  %ebx\n\t"                          \
+"popl  %ebp\n\t"                          \
+"add   $4, %esp\n\t"                      \
+"jmp   *%ecx\n\t"                         \
+"ud2\n\t")                                \
+/**/
+
+BOOST_COROUTINE_swapcontext(swapcontext_stack);
+BOOST_COROUTINE_swapcontext(swapcontext_stack2);
+BOOST_COROUTINE_swapcontext(swapcontext_stack3);
+
+#undef BOOST_COROUTINE_swapcontext
Added: sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext64.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2006/coroutine/trunk/libs/coroutine/src/swapcontext64.cpp	2007-11-28 12:20:20 EST (Wed, 28 Nov 2007)
@@ -0,0 +1,79 @@
+//  Copyright (c) 2007 Robert Perricone
+//  Copyright (c) 2007 Hartmut Kaiser
+//
+//  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)
+
+#if !defined(__x86_64__)
+#error This file is for x86 CPUs only.
+#endif
+
+#if !defined(__GNUC__)
+#error This file requires compilation with gcc.
+#endif
+
+/*
+ *  This file should really be a plain assembler file.
+ *  Unfortunately Boost.Build v2 doesn't handle asm files (yet).
+ *  For now resort to inline asm.
+ */
+
+//     RDI is &from.sp	
+//     RSI is to.sp
+//
+//     This is the simplest version of swapcontext
+//     It saves registers on the old stack, saves the old stack pointer,
+//     load the new stack pointer, pop registers from the new stack
+//     and returns to new caller.
+//
+//     RDI is set to be the parameter for the function to be called.
+//     The first time RDI is the first parameter of the trampoline.
+//     Otherwise it is simply discarded.
+//
+//     NOTE: This function should work on any IA64 CPU.
+//     NOTE: The biggest penalty is the last jump that
+//           will be always mis-predicted (~50 cycles on P4).
+//
+//     We try to make its address available as soon as possible
+//     to try to reduce the penalty. Doing a return instead of a
+//
+//        'add $8, %esp'
+//        'jmp *%ecx'
+//
+//     really kills performance.
+//
+//     NOTE: popl is slightly better than mov+add to pop registers
+//           so is pushl rather than mov+sub.
+
+#define BOOST_COROUTINE_SWAPCONTEXT(name)                                     \
+    asm volatile (                                                            \
+        ".text \n\t"                                                          \
+        ".global " #name "\n\t"                                               \
+        ".type " #name ", @function\n\t"                                      \
+        ".align 16\n"                                                         \
+    #name ":\n\t"                                                             \
+        "movq  32(%rsi), %rcx\n\t"                                            \
+        "pushq %rbp\n\t"                                                      \
+        "pushq %rbx\n\t"                                                      \
+        "pushq %rax\n\t"                                                      \
+        "pushq %rdx\n\t"                                                      \
+        "movq  %rsp, (%rdi)\n\t"                                              \
+        "movq  %rsi, %rsp\n\t"                                                \
+        "popq  %rdx\n\t"                                                      \
+        "popq  %rax\n\t"                                                      \
+        "popq  %rbx\n\t"                                                      \
+        "popq  %rbp\n\t"                                                      \
+        "movq 48(%rsi), %rdi\n\t"                                             \
+        "add   $8, %rsp\n\t"                                                  \
+        "jmp   *%rcx\n\t"                                                     \
+        "ud2\n\t"                                                             \
+    )                                                                         \
+/**/
+
+BOOST_COROUTINE_SWAPCONTEXT(swapcontext_stack);
+BOOST_COROUTINE_SWAPCONTEXT(swapcontext_stack2);
+BOOST_COROUTINE_SWAPCONTEXT(swapcontext_stack3);
+
+#undef BOOST_COROUTINE_SWAPCONTEXT
+