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 #include "boost/context/stack_traits.hpp"
8
9 extern "C" {
10 #include <signal.h>
11 #include <sys/resource.h>
12 #include <sys/time.h>
13 #include <unistd.h>
14 }
15
16 //#if _POSIX_C_SOURCE >= 200112L
17
18 #include <algorithm>
19 #include <cmath>
20
21 #include <boost/assert.hpp>
22 #include <boost/config.hpp>
23 #if defined(BOOST_NO_CXX11_HDR_MUTEX)
24 # include <boost/thread.hpp>
25 #else
26 # include <mutex>
27 #endif
28
29 #if !defined (SIGSTKSZ)
30 # define SIGSTKSZ (32768) // 32kb minimum allowable stack
31 # define UDEF_SIGSTKSZ
32 #endif
33
34 #if !defined (MINSIGSTKSZ)
35 # define MINSIGSTKSZ (131072) // 128kb recommended stack size
36 # define UDEF_MINSIGSTKSZ
37 #endif
38
39 #ifdef BOOST_HAS_ABI_HEADERS
40 # include BOOST_ABI_PREFIX
41 #endif
42
43 namespace {
44
pagesize_(std::size_t * size)45 void pagesize_( std::size_t * size) BOOST_NOEXCEPT_OR_NOTHROW {
46 // conform to POSIX.1-2001
47 * size = ::sysconf( _SC_PAGESIZE);
48 }
49
stacksize_limit_(rlimit * limit)50 void stacksize_limit_( rlimit * limit) BOOST_NOEXCEPT_OR_NOTHROW {
51 // conforming to POSIX.1-2001
52 ::getrlimit( RLIMIT_STACK, limit);
53 }
54
pagesize()55 std::size_t pagesize() BOOST_NOEXCEPT_OR_NOTHROW {
56 static std::size_t size = 0;
57 #if defined(BOOST_NO_CXX11_HDR_MUTEX)
58 static boost::once_flag flag = BOOST_ONCE_INIT;
59 boost::call_once( flag, pagesize_, & size);
60 #else
61 static std::once_flag flag;
62 std::call_once( flag, pagesize_, & size);
63 #endif
64 return size;
65 }
66
stacksize_limit()67 rlimit stacksize_limit() BOOST_NOEXCEPT_OR_NOTHROW {
68 static rlimit limit;
69 #if defined(BOOST_NO_CXX11_HDR_MUTEX)
70 static boost::once_flag flag = BOOST_ONCE_INIT;
71 boost::call_once( flag, stacksize_limit_, & limit);
72 #else
73 static std::once_flag flag;
74 std::call_once( flag, stacksize_limit_, & limit);
75 #endif
76 return limit;
77 }
78
79 }
80
81 namespace boost {
82 namespace context {
83
84 bool
is_unbounded()85 stack_traits::is_unbounded() BOOST_NOEXCEPT_OR_NOTHROW {
86 return RLIM_INFINITY == stacksize_limit().rlim_max;
87 }
88
89 std::size_t
page_size()90 stack_traits::page_size() BOOST_NOEXCEPT_OR_NOTHROW {
91 return pagesize();
92 }
93
94 std::size_t
default_size()95 stack_traits::default_size() BOOST_NOEXCEPT_OR_NOTHROW {
96 return 128 * 1024;
97 }
98
99 std::size_t
minimum_size()100 stack_traits::minimum_size() BOOST_NOEXCEPT_OR_NOTHROW {
101 return MINSIGSTKSZ;
102 }
103
104 std::size_t
maximum_size()105 stack_traits::maximum_size() BOOST_NOEXCEPT_OR_NOTHROW {
106 BOOST_ASSERT( ! is_unbounded() );
107 return static_cast< std::size_t >( stacksize_limit().rlim_max);
108 }
109
110 }}
111
112 #ifdef BOOST_HAS_ABI_HEADERS
113 # include BOOST_ABI_SUFFIX
114 #endif
115
116 #ifdef UDEF_SIGSTKSZ
117 # undef SIGSTKSZ;
118 #endif
119
120 #ifdef UDEF_MINSIGSTKSZ
121 # undef MINSIGSTKSZ
122 #endif
123