1 2 // Copyright Oliver Kowalke 2014. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 #ifndef BOOST_CONTEXT_PROTECTED_FIXEDSIZE_H 8 #define BOOST_CONTEXT_PROTECTED_FIXEDSIZE_H 9 10 extern "C" { 11 #include <windows.h> 12 } 13 14 #include <cmath> 15 #include <cstddef> 16 #include <new> 17 18 #include <boost/config.hpp> 19 #include <boost/core/ignore_unused.hpp> 20 21 #include <boost/context/detail/config.hpp> 22 #include <boost/context/stack_context.hpp> 23 #include <boost/context/stack_traits.hpp> 24 25 #ifdef BOOST_HAS_ABI_HEADERS 26 # include BOOST_ABI_PREFIX 27 #endif 28 29 namespace boost { 30 namespace context { 31 32 template< typename traitsT > 33 class basic_protected_fixedsize_stack { 34 private: 35 std::size_t size_; 36 37 public: 38 typedef traitsT traits_type; 39 basic_protected_fixedsize_stack(std::size_t size=traits_type::default_size ())40 basic_protected_fixedsize_stack( std::size_t size = traits_type::default_size() ) BOOST_NOEXCEPT_OR_NOTHROW : 41 size_( size) { 42 } 43 allocate()44 stack_context allocate() { 45 // calculate how many pages are required 46 const std::size_t pages( 47 static_cast< std::size_t >( 48 std::ceil( 49 static_cast< float >( size_) / traits_type::page_size() ) ) ); 50 // add one page at bottom that will be used as guard-page 51 const std::size_t size__ = ( pages + 1) * traits_type::page_size(); 52 53 void * vp = ::VirtualAlloc( 0, size__, MEM_COMMIT, PAGE_READWRITE); 54 if ( ! vp) throw std::bad_alloc(); 55 56 DWORD old_options; 57 const BOOL result = ::VirtualProtect( 58 vp, traits_type::page_size(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options); 59 boost::ignore_unused(result); 60 BOOST_ASSERT( FALSE != result); 61 62 stack_context sctx; 63 sctx.size = size__; 64 sctx.sp = static_cast< char * >( vp) + sctx.size; 65 return sctx; 66 } 67 deallocate(stack_context & sctx)68 void deallocate( stack_context & sctx) BOOST_NOEXCEPT_OR_NOTHROW { 69 BOOST_ASSERT( sctx.sp); 70 71 void * vp = static_cast< char * >( sctx.sp) - sctx.size; 72 ::VirtualFree( vp, 0, MEM_RELEASE); 73 } 74 }; 75 76 typedef basic_protected_fixedsize_stack< stack_traits > protected_fixedsize_stack; 77 78 }} 79 80 #ifdef BOOST_HAS_ABI_HEADERS 81 # include BOOST_ABI_SUFFIX 82 #endif 83 84 #endif // BOOST_CONTEXT_PROTECTED_FIXEDSIZE_H 85