• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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