Ticket #4865: boost_coroutine_linux64.diff
File boost_coroutine_linux64.diff, 10.5 KB (added by , 12 years ago) |
---|
-
boost/coroutine/detail/context_linux64.hpp
1 1 // Copyright (c) 2007 Robert Perricone 2 // Copyright (c) 2007 Hartmut Kaiser2 // Copyright (c) 2007-2009 Hartmut Kaiser 3 3 // 4 4 // Distributed under the Boost Software License, Version 1.0. 5 5 // (See accompanying file LICENSE_1_0.txt or copy at … … 28 28 extern "C" void swapcontext_stack3 (void***, void**) throw(); 29 29 30 30 /////////////////////////////////////////////////////////////////////////////// 31 namespace boost { namespace coroutines { namespace detail { 32 namespace oslinux64 31 namespace boost { namespace coroutines { 32 33 // some platforms need special preparation of the main thread 34 struct prepare_main_thread 33 35 { 36 prepare_main_thread() {} 37 ~prepare_main_thread() {} 38 }; 39 40 namespace detail { namespace oslinux64 41 { 34 42 template<typename T> 35 43 void trampoline(T* fun); 36 44 37 45 template<typename T> 38 46 inline void 39 47 trampoline(T* fun) … … 42 50 std::abort(); 43 51 } 44 52 53 class ia64_gcc_context_impl; 54 45 55 class ia64_gcc_context_impl_base 46 56 { 47 57 public: … … 66 76 * and restores the context in @p to. 67 77 * @note This function is found by ADL. 68 78 */ 69 friend void 70 swap_context(ia64_gcc_context_impl_base& from, 71 ia64_gcc_context_impl_base const& to, 72 default_hint) 73 { 74 to.prefetch(); 75 swapcontext_stack(&from.m_sp, to.m_sp); 76 } 79 friend void swap_context(ia64_gcc_context_impl_base& from, 80 ia64_gcc_context_impl const& to, default_hint); 77 81 78 82 #ifndef BOOST_COROUTINE_NO_SEPARATE_CALL_SITES 79 friend void 80 swap_context(ia64_gcc_context_impl_base& from, 81 ia64_gcc_context_impl_base const& to, 82 yield_hint) 83 { 84 to.prefetch(); 85 swapcontext_stack2(&from.m_sp, to.m_sp); 86 } 83 friend void swap_context(ia64_gcc_context_impl& from, 84 ia64_gcc_context_impl_base const& to, yield_hint); 87 85 88 friend void 89 swap_context(ia64_gcc_context_impl_base& from, 90 ia64_gcc_context_impl_base const& to, 91 yield_to_hint) 92 { 93 to.prefetch(); 94 swapcontext_stack3(&from.m_sp, to.m_sp); 95 } 86 friend void swap_context(ia64_gcc_context_impl& from, 87 ia64_gcc_context_impl_base const& to, yield_to_hint); 96 88 #endif 97 89 98 90 protected: … … 102 94 class ia64_gcc_context_impl : public ia64_gcc_context_impl_base 103 95 { 104 96 public: 105 enum { default_stack_size = 8192 };106 97 enum { default_stack_size = 2*8192 }; 98 107 99 typedef ia64_gcc_context_impl_base context_impl_base; 108 100 109 ia64_gcc_context_impl() : 110 m_stack(0) {} 111 101 ia64_gcc_context_impl() 102 : m_stack(0) 103 {} 104 112 105 /** 113 106 * Create a context that on restore invokes Functor on 114 107 * a new stack. The stack size can be optionally specified. … … 120 113 { 121 114 BOOST_ASSERT(m_stack); 122 115 m_sp = ((void**)m_stack + (m_stack_size/sizeof(void*))); 123 116 117 *(void**)m_stack = (void*)~0; // fill the last word with ones 118 124 119 typedef void fun(Functor*); 125 120 fun * funp = trampoline; 126 121 122 // we have to make sure that the stack pointer is aligned on a 16 Byte 123 // boundary when the code is entering the trampoline (the stack itself 124 // is already properly aligned) 125 *--m_sp = 0; // additional alignment 126 127 127 *--m_sp = &cb; // parm 0 of trampoline; 128 128 *--m_sp = 0; // dummy return address for trampoline 129 129 *--m_sp = (void*) funp ;// return addr (here: start addr) NOTE: the unsafe cast is safe on IA64 130 *--m_sp = 0; // rbp 131 *--m_sp = 0; // rbx 132 *--m_sp = 0; // rsi 133 *--m_sp = 0; // rdi 130 *--m_sp = 0; // rbp 131 *--m_sp = 0; // rbx 132 *--m_sp = 0; // rsi 133 *--m_sp = 0; // rdi 134 *--m_sp = 0; // r12 135 *--m_sp = 0; // r13 136 *--m_sp = 0; // r14 137 *--m_sp = 0; // r15 134 138 } 135 139 136 140 ~ia64_gcc_context_impl() … … 139 143 posix::free_stack(m_stack, m_stack_size); 140 144 } 141 145 146 friend void swap_context(ia64_gcc_context_impl_base& from, 147 ia64_gcc_context_impl const& to, default_hint); 148 149 #ifndef BOOST_COROUTINE_NO_SEPARATE_CALL_SITES 150 friend void swap_context(ia64_gcc_context_impl& from, 151 ia64_gcc_context_impl_base const& to, yield_hint); 152 153 friend void swap_context(ia64_gcc_context_impl& from, 154 ia64_gcc_context_impl_base const& to, yield_to_hint); 155 #endif 156 142 157 private: 143 158 std::ptrdiff_t m_stack_size; 144 159 void * m_stack; 145 160 }; 146 161 147 162 typedef ia64_gcc_context_impl context_impl; 163 164 /** 165 * Free function. Saves the current context in @p from 166 * and restores the context in @p to. 167 * @note This function is found by ADL. 168 */ 169 inline void swap_context(ia64_gcc_context_impl_base& from, 170 ia64_gcc_context_impl const& to, default_hint) 171 { 172 // BOOST_ASSERT(*(void**)to.m_stack == (void*)~0); 173 to.prefetch(); 174 swapcontext_stack(&from.m_sp, to.m_sp); 175 } 176 177 #ifndef BOOST_COROUTINE_NO_SEPARATE_CALL_SITES 178 inline void swap_context(ia64_gcc_context_impl& from, 179 ia64_gcc_context_impl_base const& to, yield_hint) 180 { 181 // BOOST_ASSERT(*(void**)from.m_stack == (void*)~0); 182 to.prefetch(); 183 swapcontext_stack2(&from.m_sp, to.m_sp); 184 } 185 186 inline void swap_context(ia64_gcc_context_impl& from, 187 ia64_gcc_context_impl_base const& to, yield_to_hint) 188 { 189 // BOOST_ASSERT(*(void**)from.m_stack == (void*)~0); 190 to.prefetch(); 191 swapcontext_stack3(&from.m_sp, to.m_sp); 192 } 193 #endif 194 148 195 } 149 196 }}} 150 197 … … 165 212 166 213 #endif 167 214 215 -
boost/coroutine/detail/posix_utility.hpp
38 38 #include <cerrno> 39 39 #include <cstddef> 40 40 #include <cstdlib> 41 #include <cstring> 41 42 #include <iostream> 42 43 #include <boost/type_traits.hpp> 43 44 /** … … 134 135 0 135 136 ); 136 137 if(stack == MAP_FAILED) { 137 std::cerr << strerror(errno)<<"\n";138 std::cerr << strerror(errno) << "\n"; 138 139 abort(); 139 140 } 140 141 return stack; -
boost/coroutine/detail/coroutine_impl.hpp
56 56 typedef ContextImpl context_impl; 57 57 typedef CoroutineType coroutine_type; 58 58 typedef coroutine_impl<coroutine_type, context_impl> type; 59 typedef context_base<context_impl> context_base ;59 typedef context_base<context_impl> context_base2; 60 60 typedef typename coroutine_type::arg_slot_type arg_slot_type; 61 61 typedef typename coroutine_type::result_type result_type; 62 62 typedef typename coroutine_type::result_slot_type result_slot_type; … … 65 65 66 66 template<typename DerivedType> 67 67 coroutine_impl(DerivedType * this_, std::ptrdiff_t stack_size) : 68 context_base (*this_, stack_size),68 context_base2(*this_, stack_size), 69 69 m_arg(0), 70 70 m_result(0){} 71 71 -
libs/coroutine/src/swapcontext64.cpp
19 19 * For now resort to inline asm. 20 20 */ 21 21 22 // RDI is &from.sp 22 // RDI is &from.sp 23 23 // RSI is to.sp 24 24 // 25 25 // This is the simplest version of swapcontext … … 53 53 ".type " #name ", @function\n\t" \ 54 54 ".align 16\n" \ 55 55 #name ":\n\t" \ 56 "movq 32(%rsi), %rcx\n\t" \56 "movq 64(%rsi), %rcx\n\t" \ 57 57 "pushq %rbp\n\t" \ 58 58 "pushq %rbx\n\t" \ 59 59 "pushq %rax\n\t" \ 60 60 "pushq %rdx\n\t" \ 61 "pushq %r12\n\t" \ 62 "pushq %r13\n\t" \ 63 "pushq %r14\n\t" \ 64 "pushq %r15\n\t" \ 61 65 "movq %rsp, (%rdi)\n\t" \ 62 66 "movq %rsi, %rsp\n\t" \ 67 "popq %r15\n\t" \ 68 "popq %r14\n\t" \ 69 "popq %r13\n\t" \ 70 "popq %r12\n\t" \ 63 71 "popq %rdx\n\t" \ 64 72 "popq %rax\n\t" \ 65 73 "popq %rbx\n\t" \ 66 74 "popq %rbp\n\t" \ 67 "movq 48(%rsi), %rdi\n\t" \75 "movq 80(%rsi), %rdi\n\t" \ 68 76 "add $8, %rsp\n\t" \ 69 77 "jmp *%rcx\n\t" \ 70 78 "ud2\n\t" \ 71 ) \79 ) 72 80 /**/ 73 81 74 82 BOOST_COROUTINE_SWAPCONTEXT(swapcontext_stack);