Ticket #4865: boost_coroutine_linux64.diff

File boost_coroutine_linux64.diff, 10.5 KB (added by cJ-boost@…, 12 years ago)

collection of fixes

  • boost/coroutine/detail/context_linux64.hpp

     
    11//  Copyright (c) 2007 Robert Perricone
    2 //  Copyright (c) 2007 Hartmut Kaiser
     2//  Copyright (c) 2007-2009 Hartmut Kaiser
    33//
    44//  Distributed under the Boost Software License, Version 1.0.
    55//  (See accompanying file LICENSE_1_0.txt or copy at
     
    2828extern "C" void swapcontext_stack3 (void***, void**) throw();
    2929
    3030///////////////////////////////////////////////////////////////////////////////
    31 namespace boost { namespace coroutines { namespace detail {
    32   namespace oslinux64
     31namespace boost { namespace coroutines {
     32
     33  // some platforms need special preparation of the main thread
     34  struct prepare_main_thread
    3335  {
     36      prepare_main_thread() {}
     37      ~prepare_main_thread() {}
     38  };
     39
     40  namespace detail { namespace oslinux64
     41  {
    3442    template<typename T>
    3543    void trampoline(T* fun);
    36    
     44
    3745    template<typename T>
    3846    inline void
    3947    trampoline(T* fun)
     
    4250      std::abort();
    4351    }
    4452
     53    class ia64_gcc_context_impl;
     54
    4555    class ia64_gcc_context_impl_base
    4656    {
    4757    public:
     
    6676       * and restores the context in @p to.
    6777       * @note This function is found by ADL.
    6878       */     
    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);
    7781
    7882#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);
    8785
    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);
    9688#endif
    9789
    9890    protected:
     
    10294    class ia64_gcc_context_impl : public ia64_gcc_context_impl_base
    10395    {
    10496    public:
    105       enum { default_stack_size = 8192 };
    106      
     97      enum { default_stack_size = 2*8192 };
     98
    10799      typedef ia64_gcc_context_impl_base context_impl_base;
    108100
    109       ia64_gcc_context_impl() :
    110         m_stack(0) {}
    111        
     101      ia64_gcc_context_impl()
     102        : m_stack(0)
     103      {}
     104
    112105      /**
    113106       * Create a context that on restore invokes Functor on
    114107       *  a new stack. The stack size can be optionally specified.
     
    120113      {
    121114        BOOST_ASSERT(m_stack);
    122115        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
    124119        typedef void fun(Functor*);
    125120        fun * funp = trampoline;
    126121
     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
    127127        *--m_sp = &cb;     // parm 0 of trampoline;
    128128        *--m_sp = 0;       // dummy return address for trampoline
    129129        *--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
    134138      }
    135139     
    136140      ~ia64_gcc_context_impl()
     
    139143          posix::free_stack(m_stack, m_stack_size);
    140144      }
    141145
     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
    142157    private:
    143158      std::ptrdiff_t m_stack_size;
    144159      void * m_stack;
    145160    };
    146161   
    147162    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
    148195  }
    149196}}}
    150197
     
    165212
    166213#endif
    167214
     215
  • boost/coroutine/detail/posix_utility.hpp

     
    3838#include <cerrno>
    3939#include <cstddef>
    4040#include <cstdlib>
     41#include <cstring>
    4142#include <iostream>
    4243#include <boost/type_traits.hpp>
    4344/**
     
    134135                          0
    135136                          );
    136137    if(stack == MAP_FAILED) {
    137       std::cerr <<strerror(errno)<<"\n";
     138      std::cerr << strerror(errno) << "\n";
    138139      abort();
    139140    }
    140141    return stack;
  • boost/coroutine/detail/coroutine_impl.hpp

     
    5656    typedef ContextImpl context_impl;
    5757    typedef CoroutineType coroutine_type;
    5858    typedef coroutine_impl<coroutine_type, context_impl> type;
    59     typedef context_base<context_impl> context_base;
     59    typedef context_base<context_impl> context_base2;
    6060    typedef typename coroutine_type::arg_slot_type arg_slot_type;
    6161    typedef typename coroutine_type::result_type result_type;
    6262    typedef typename coroutine_type::result_slot_type result_slot_type;
     
    6565 
    6666    template<typename DerivedType>
    6767        coroutine_impl(DerivedType * this_, std::ptrdiff_t stack_size) :
    68       context_base(*this_, stack_size),
     68      context_base2(*this_, stack_size),
    6969        m_arg(0),
    7070        m_result(0){}
    7171               
  • libs/coroutine/src/swapcontext64.cpp

     
    1919 *  For now resort to inline asm.
    2020 */
    2121
    22 //     RDI is &from.sp 
     22//     RDI is &from.sp   
    2323//     RSI is to.sp
    2424//
    2525//     This is the simplest version of swapcontext
     
    5353        ".type " #name ", @function\n\t"                                      \
    5454        ".align 16\n"                                                         \
    5555    #name ":\n\t"                                                             \
    56         "movq  32(%rsi), %rcx\n\t"                                            \
     56        "movq  64(%rsi), %rcx\n\t"                                            \
    5757        "pushq %rbp\n\t"                                                      \
    5858        "pushq %rbx\n\t"                                                      \
    5959        "pushq %rax\n\t"                                                      \
    6060        "pushq %rdx\n\t"                                                      \
     61        "pushq %r12\n\t"                                                      \
     62        "pushq %r13\n\t"                                                      \
     63        "pushq %r14\n\t"                                                      \
     64        "pushq %r15\n\t"                                                      \
    6165        "movq  %rsp, (%rdi)\n\t"                                              \
    6266        "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"                                                       \
    6371        "popq  %rdx\n\t"                                                      \
    6472        "popq  %rax\n\t"                                                      \
    6573        "popq  %rbx\n\t"                                                      \
    6674        "popq  %rbp\n\t"                                                      \
    67         "movq 48(%rsi), %rdi\n\t"                                             \
     75        "movq 80(%rsi), %rdi\n\t"                                             \
    6876        "add   $8, %rsp\n\t"                                                  \
    6977        "jmp   *%rcx\n\t"                                                     \
    7078        "ud2\n\t"                                                             \
    71     )                                                                         \
     79    )
    7280/**/
    7381
    7482BOOST_COROUTINE_SWAPCONTEXT(swapcontext_stack);