protected_fixedsize_stack.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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_PROTECTED_FIXEDSIZE_H
  6. #define BOOST_CONTEXT_PROTECTED_FIXEDSIZE_H
  7. extern "C" {
  8. #include <windows.h>
  9. }
  10. #include <cmath>
  11. #include <cstddef>
  12. #include <new>
  13. #include <boost/config.hpp>
  14. #include <boost/context/detail/config.hpp>
  15. #include <boost/context/stack_context.hpp>
  16. #include <boost/context/stack_traits.hpp>
  17. #ifdef BOOST_HAS_ABI_HEADERS
  18. # include BOOST_ABI_PREFIX
  19. #endif
  20. namespace boost {
  21. namespace context {
  22. template< typename traitsT >
  23. class basic_protected_fixedsize_stack {
  24. private:
  25. std::size_t size_;
  26. public:
  27. typedef traitsT traits_type;
  28. basic_protected_fixedsize_stack( std::size_t size = traits_type::default_size() ) BOOST_NOEXCEPT_OR_NOTHROW :
  29. size_( size) {
  30. }
  31. stack_context allocate() {
  32. // calculate how many pages are required
  33. const std::size_t pages(
  34. static_cast< std::size_t >(
  35. std::ceil(
  36. static_cast< float >( size_) / traits_type::page_size() ) ) );
  37. // add one page at bottom that will be used as guard-page
  38. const std::size_t size__ = ( pages + 1) * traits_type::page_size();
  39. void * vp = ::VirtualAlloc( 0, size__, MEM_COMMIT, PAGE_READWRITE);
  40. if ( ! vp) throw std::bad_alloc();
  41. DWORD old_options;
  42. #if defined(BOOST_DISABLE_ASSERTS)
  43. ::VirtualProtect(
  44. vp, traits_type::page_size(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
  45. #else
  46. const BOOL result = ::VirtualProtect(
  47. vp, traits_type::page_size(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
  48. BOOST_ASSERT( FALSE != result);
  49. #endif
  50. stack_context sctx;
  51. sctx.size = size__;
  52. sctx.sp = static_cast< char * >( vp) + sctx.size;
  53. return sctx;
  54. }
  55. void deallocate( stack_context & sctx) BOOST_NOEXCEPT_OR_NOTHROW {
  56. BOOST_ASSERT( sctx.sp);
  57. void * vp = static_cast< char * >( sctx.sp) - sctx.size;
  58. ::VirtualFree( vp, 0, MEM_RELEASE);
  59. }
  60. };
  61. typedef basic_protected_fixedsize_stack< stack_traits > protected_fixedsize_stack;
  62. }}
  63. #ifdef BOOST_HAS_ABI_HEADERS
  64. # include BOOST_ABI_SUFFIX
  65. #endif
  66. #endif // BOOST_CONTEXT_PROTECTED_FIXEDSIZE_H