segmented_stack.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // Copyright Oliver Kowalke 2014.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_CONTEXT_SEGMENTED_H
  6. #define BOOST_CONTEXT_SEGMENTED_H
  7. #include <cstddef>
  8. #include <new>
  9. #include <boost/config.hpp>
  10. #include <boost/context/detail/config.hpp>
  11. #include <boost/context/stack_context.hpp>
  12. #include <boost/context/stack_traits.hpp>
  13. #ifdef BOOST_HAS_ABI_HEADERS
  14. # include BOOST_ABI_PREFIX
  15. #endif
  16. // forward declaration for splitstack-functions defined in libgcc
  17. extern "C" {
  18. void *__splitstack_makecontext( std::size_t,
  19. void * [BOOST_CONTEXT_SEGMENTS],
  20. std::size_t *);
  21. void __splitstack_releasecontext( void * [BOOST_CONTEXT_SEGMENTS]);
  22. void __splitstack_resetcontext( void * [BOOST_CONTEXT_SEGMENTS]);
  23. void __splitstack_block_signals_context( void * [BOOST_CONTEXT_SEGMENTS],
  24. int * new_value, int * old_value);
  25. }
  26. namespace boost {
  27. namespace context {
  28. template< typename traitsT >
  29. class basic_segmented_stack {
  30. private:
  31. std::size_t size_;
  32. public:
  33. typedef traitsT traits_type;
  34. basic_segmented_stack( std::size_t size = traits_type::default_size() ) BOOST_NOEXCEPT_OR_NOTHROW :
  35. size_( size) {
  36. BOOST_ASSERT( traits_type::minimum_size() <= size_);
  37. BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= size_) );
  38. }
  39. stack_context allocate() {
  40. stack_context sctx;
  41. void * vp = __splitstack_makecontext( size_, sctx.segments_ctx, & sctx.size);
  42. if ( ! vp) throw std::bad_alloc();
  43. // sctx.size is already filled by __splitstack_makecontext
  44. sctx.sp = static_cast< char * >( vp) + sctx.size;
  45. int off = 0;
  46. __splitstack_block_signals_context( sctx.segments_ctx, & off, 0);
  47. return sctx;
  48. }
  49. void deallocate( stack_context & sctx) BOOST_NOEXCEPT_OR_NOTHROW {
  50. __splitstack_releasecontext( sctx.segments_ctx);
  51. }
  52. };
  53. typedef basic_segmented_stack< stack_traits > segmented_stack;
  54. # if defined(BOOST_USE_SEGMENTED_STACKS)
  55. typedef segmented_stack default_stack;
  56. # endif
  57. }}
  58. #ifdef BOOST_HAS_ABI_HEADERS
  59. # include BOOST_ABI_SUFFIX
  60. #endif
  61. #endif // BOOST_CONTEXT_SEGMENTED_H