如何在Boehm GC中使用Boost.Coroutine?

时间:2015-01-30 17:42:21

标签: c++ boehm-gc boost-context boost-coroutine

Boost.Coroutine分配自己的调用堆栈。 Boehm GC是否将这些堆栈的指针视为根,如果不是,我怎么能这样做呢?在上下文切换到协程后,Boehm终止程序。

2 个答案:

答案 0 :(得分:2)

假设Boost.Coroutine中的代码保存了一个指向它分配的调用堆栈的指针,并将其存储在"通常"之一中。用于存储指针的位置(例如,一些指针变量)。

如果是这种情况,那么是的,GC会"追逐"从存储到调用堆栈的变量的指针,并从那里(递归地)通过它包含的任何指针。

答案 1 :(得分:1)

当前boost并没有提供挂钩分段堆栈分配的方法,因此这是固定大小堆栈的一种解决方案。

#include <gc/gc.h>
#include <gc/gc_cpp.h>
#include <boost/coroutine2/coroutine.hpp>
#include <boost/coroutine2/protected_fixedsize_stack.hpp>
#include <boost/context/stack_context.hpp>

class BoehmGCStackAllocator {
    boost::coroutines2::protected_fixedsize_stack stack;

    // This is specific to boost::coroutines2::protected_fixedsize_stack.
    // The stack protection page is included in sctx.size, so we have to
    // subtract one page size from the stack size.
    std::size_t pfss_usable_stack_size(boost::context::stack_context &sctx) {
      return sctx.size - boost::context::stack_traits::page_size();
    }

  public:
    boost::context::stack_context allocate() {
        auto sctx = stack.allocate();

        // Despite what the boost docs warn, the only *implemented* stack direction
        // is "down". This is why we subtract the stack size.
        GC_add_roots(static_cast<char *>(sctx.sp) - pfss_usable_stack_size(sctx), sctx.sp);
        return sctx;
    }

    void deallocate(boost::context::stack_context sctx) {
        GC_remove_roots(static_cast<char *>(sctx.sp) - pfss_usable_stack_size(sctx), sctx.sp);
        stack.deallocate(sctx);
    }

};

然后在创建协程时提供它。

auto coro = boost::coroutines2::coroutine<std::string>::pull_type(BoehmGCStackAllocator{}, [&](coro_t::push_type & yield) {
   // ...
}