8 #ifndef SINGLETON_POOLED_FIXEDSIZE_STACK_H
9 #define SINGLETON_POOLED_FIXEDSIZE_STACK_H
12 #include <boost/pool/poolfwd.hpp>
17 #include <boost/assert.hpp>
18 #include <boost/config.hpp>
19 #include <boost/intrusive_ptr.hpp>
20 #include <boost/pool/singleton_pool.hpp>
22 #include <boost/context/detail/config.hpp>
23 #include <boost/context/stack_context.hpp>
24 #include <boost/context/stack_traits.hpp>
28 template <std::
size_t stack_size,
typename traitsT>
33 std::atomic<std::size_t> use_count_;
35 typedef boost::singleton_pool<pool_tag, stack_size, boost::default_user_allocator_malloc_free>
39 storage() : use_count_(0) {
40 BOOST_ASSERT(traits_type::is_unbounded() || (traits_type::maximum_size() >= stack_size));
43 boost::context::stack_context
allocate() {
44 void* vp = storage_pool::malloc();
46 throw std::bad_alloc();
48 boost::context::stack_context sctx;
49 sctx.size = stack_size;
50 sctx.sp =
static_cast<char*
>(vp) + sctx.size;
51 #
if defined(BOOST_USE_VALGRIND)
52 sctx.valgrind_stack_id = VALGRIND_STACK_REGISTER(sctx.sp, vp);
57 void deallocate(boost::context::stack_context& sctx) BOOST_NOEXCEPT_OR_NOTHROW {
58 BOOST_ASSERT(sctx.sp);
59 BOOST_ASSERT(traits_type::is_unbounded() || (traits_type::maximum_size() >= sctx.size));
61 #if defined(BOOST_USE_VALGRIND)
62 VALGRIND_STACK_DEREGISTER(sctx.valgrind_stack_id);
64 void* vp =
static_cast<char*
>(sctx.sp) - sctx.size;
65 storage_pool::free(vp);
68 friend void intrusive_ptr_add_ref(storage* s) noexcept {
72 friend void intrusive_ptr_release(storage* s) noexcept {
73 if (0 == --s->use_count_) {
79 boost::intrusive_ptr<storage> storage_;
86 std::size_t = 0) BOOST_NOEXCEPT_OR_NOTHROW
88 storage_(new storage()) {}
91 return storage_->allocate();
94 void deallocate(boost::context::stack_context& sctx) BOOST_NOEXCEPT_OR_NOTHROW {
95 storage_->deallocate(sctx);
99 template <std::
size_t stack_size>
105 #endif // SINGLETON_POOLED_FIXEDSIZE_STACK_H