protected_fixedsize_stack.hpp 2.2 KB

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