MOTION  0.01
Framework for mixed-protocol multi-party computation
singleton_pooled_fixedsize_stack.hpp
Go to the documentation of this file.
1 // This file is adapted from context/pooled_fixedsize_stack.hpp of Boost 1.72.0.
2 
3 // Copyright Oliver Kowalke 2014 / Lennart Braun 2020
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 
8 #ifndef SINGLETON_POOLED_FIXEDSIZE_STACK_H
9 #define SINGLETON_POOLED_FIXEDSIZE_STACK_H
10 
11 #include <atomic>
12 #include <boost/pool/poolfwd.hpp>
13 #include <cstddef>
14 #include <cstdlib>
15 #include <new>
16 
17 #include <boost/assert.hpp>
18 #include <boost/config.hpp>
19 #include <boost/intrusive_ptr.hpp>
20 #include <boost/pool/singleton_pool.hpp>
21 
22 #include <boost/context/detail/config.hpp>
23 #include <boost/context/stack_context.hpp>
24 #include <boost/context/stack_traits.hpp>
25 
26 // clang-format off
27 
28 template <std::size_t stack_size, typename traitsT>
30 private:
31  class storage {
32  private:
33  std::atomic<std::size_t> use_count_;
34  struct pool_tag {};
35  typedef boost::singleton_pool<pool_tag, stack_size, boost::default_user_allocator_malloc_free>
36  storage_pool;
37 
38  public:
39  storage() : use_count_(0) {
40  BOOST_ASSERT(traits_type::is_unbounded() || (traits_type::maximum_size() >= stack_size));
41  }
42 
43  boost::context::stack_context allocate() {
44  void* vp = storage_pool::malloc();
45  if (!vp) {
46  throw std::bad_alloc();
47  }
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);
53 #endif
54  return sctx;
55  }
56 
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));
60 
61 #if defined(BOOST_USE_VALGRIND)
62  VALGRIND_STACK_DEREGISTER(sctx.valgrind_stack_id);
63 #endif
64  void* vp = static_cast<char*>(sctx.sp) - sctx.size;
65  storage_pool::free(vp);
66  }
67 
68  friend void intrusive_ptr_add_ref(storage* s) noexcept {
69  ++s->use_count_;
70  }
71 
72  friend void intrusive_ptr_release(storage* s) noexcept {
73  if (0 == --s->use_count_) {
74  delete s;
75  }
76  }
77  };
78 
79  boost::intrusive_ptr<storage> storage_;
80 
81 public:
82  typedef traitsT traits_type;
83 
84  // parameters are kept for compatibility of interface
85  basic_singleton_pooled_fixedsize_stack(std::size_t = 0, std::size_t = 0,
86  std::size_t = 0) BOOST_NOEXCEPT_OR_NOTHROW
87 :
88  storage_(new storage()) {}
89 
90  boost::context::stack_context allocate() {
91  return storage_->allocate();
92  }
93 
94  void deallocate(boost::context::stack_context& sctx) BOOST_NOEXCEPT_OR_NOTHROW {
95  storage_->deallocate(sctx);
96  }
97 };
98 
99 template <std::size_t stack_size>
102 
103 // clang-format on
104 
105 #endif // SINGLETON_POOLED_FIXEDSIZE_STACK_H
basic_singleton_pooled_fixedsize_stack::deallocate
void deallocate(boost::context::stack_context &sctx) noexcept
Definition: singleton_pooled_fixedsize_stack.hpp:94
basic_singleton_pooled_fixedsize_stack
Definition: singleton_pooled_fixedsize_stack.hpp:29
basic_singleton_pooled_fixedsize_stack::traits_type
traitsT traits_type
Definition: singleton_pooled_fixedsize_stack.hpp:82
basic_singleton_pooled_fixedsize_stack::allocate
boost::context::stack_context allocate()
Definition: singleton_pooled_fixedsize_stack.hpp:90
basic_singleton_pooled_fixedsize_stack::basic_singleton_pooled_fixedsize_stack
basic_singleton_pooled_fixedsize_stack(std::size_t=0, std::size_t=0, std::size_t=0) noexcept
Definition: singleton_pooled_fixedsize_stack.hpp:85