• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 //          Copyright Oliver Kowalke 2009.
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 #include "boost/coroutine/stack_traits.hpp"
8 
9 extern "C" {
10 #include <windows.h>
11 }
12 
13 //#if defined (BOOST_WINDOWS) || _POSIX_C_SOURCE >= 200112L
14 
15 #include <algorithm>
16 #include <cmath>
17 #include <cstddef>
18 #include <cstring>
19 #include <stdexcept>
20 
21 #include <boost/assert.hpp>
22 #include <boost/coroutine/detail/config.hpp>
23 #include <boost/thread.hpp>
24 
25 #include <boost/coroutine/stack_context.hpp>
26 
27 // x86_64
28 // test x86_64 before i386 because icc might
29 // define __i686__ for x86_64 too
30 #if defined(__x86_64__) || defined(__x86_64) \
31     || defined(__amd64__) || defined(__amd64) \
32     || defined(_M_X64) || defined(_M_AMD64)
33 
34 // Windows seams not to provide a constant or function
35 // telling the minimal stacksize
36 # define MIN_STACKSIZE  8 * 1024
37 #else
38 # define MIN_STACKSIZE  4 * 1024
39 #endif
40 
41 #ifdef BOOST_HAS_ABI_HEADERS
42 #  include BOOST_ABI_PREFIX
43 #endif
44 
45 namespace {
46 
system_info_(SYSTEM_INFO * si)47 void system_info_( SYSTEM_INFO * si)
48 { ::GetSystemInfo( si); }
49 
system_info()50 SYSTEM_INFO system_info()
51 {
52     static SYSTEM_INFO si;
53     static boost::once_flag flag;
54     boost::call_once( flag, static_cast< void(*)( SYSTEM_INFO *) >( system_info_), & si);
55     return si;
56 }
57 
pagesize()58 std::size_t pagesize()
59 { return static_cast< std::size_t >( system_info().dwPageSize); }
60 
page_count(std::size_t stacksize)61 std::size_t page_count( std::size_t stacksize)
62 {
63     return static_cast< std::size_t >(
64         std::floor(
65             static_cast< float >( stacksize) / pagesize() ) );
66 }
67 
68 }
69 
70 namespace boost {
71 namespace coroutines {
72 
73 // Windows seams not to provide a limit for the stacksize
74 // libcoco uses 32k+4k bytes as minimum
75 bool
is_unbounded()76 stack_traits::is_unbounded() BOOST_NOEXCEPT
77 { return true; }
78 
79 std::size_t
page_size()80 stack_traits::page_size() BOOST_NOEXCEPT
81 { return pagesize(); }
82 
83 std::size_t
default_size()84 stack_traits::default_size() BOOST_NOEXCEPT
85 {
86     std::size_t size = 64 * 1024; // 64 kB
87     if ( is_unbounded() )
88         return (std::max)( size, minimum_size() );
89 
90     BOOST_ASSERT( maximum_size() >= minimum_size() );
91     return maximum_size() == minimum_size()
92         ? minimum_size()
93         : ( std::min)( size, maximum_size() );
94 }
95 
96 // because Windows seams not to provide a limit for minimum stacksize
97 std::size_t
minimum_size()98 stack_traits::minimum_size() BOOST_NOEXCEPT
99 { return MIN_STACKSIZE; }
100 
101 // because Windows seams not to provide a limit for maximum stacksize
102 // maximum_size() can never be called (pre-condition ! is_unbounded() )
103 std::size_t
maximum_size()104 stack_traits::maximum_size() BOOST_NOEXCEPT
105 {
106     BOOST_ASSERT( ! is_unbounded() );
107     return  1 * 1024 * 1024 * 1024; // 1GB
108 }
109 
110 }}
111 
112 #ifdef BOOST_HAS_ABI_HEADERS
113 #  include BOOST_ABI_SUFFIX
114 #endif
115