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