libcopp  2.2.0
stack_traits_posix.cpp
Go to the documentation of this file.
1 // Copyright 2023 owent
2 
3 #include <libcopp/utils/config/libcopp_build_features.h>
4 
5 #if !defined(_MSC_VER)
6 
8 
9 // clang-format off
10 #include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
11 // clang-format on
12 extern "C" {
13 # include <assert.h>
14 # include <signal.h>
15 # include <sys/resource.h>
16 # include <sys/time.h>
17 # include <unistd.h>
18 }
19 
20 // #if _POSIX_C_SOURCE >= 200112L
21 
22 # include <algorithm>
23 # include <cmath>
24 # include <limits>
25 
26 # if !defined(MINSIGSTKSZ)
27 # define MINSIGSTKSZ (128 * 1024)
28 # define UDEF_MINSIGSTKSZ
29 # endif
30 
31 # ifdef COPP_HAS_ABI_HEADERS
32 # include COPP_ABI_PREFIX
33 # endif
34 // clang-format off
35 #include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
36 // clang-format on
37 
38 LIBCOPP_COPP_NAMESPACE_BEGIN
39 
40 namespace detail {
41 static std::size_t pagesize() {
42  std::size_t size = ::sysconf(_SC_PAGESIZE);
43  return size;
44 }
45 
46 static rlimit stacksize_limit_() {
47  rlimit limit;
48  // conforming to POSIX.1-2001
49  ::getrlimit(RLIMIT_STACK, &limit);
50  return limit;
51 }
52 
53 static rlimit stacksize_limit() {
54  static rlimit limit = stacksize_limit_();
55  return limit;
56 }
57 } // namespace detail
58 
59 LIBCOPP_COPP_API bool stack_traits::is_unbounded() LIBCOPP_MACRO_NOEXCEPT {
60  return RLIM_INFINITY == detail::stacksize_limit().rlim_max;
61 }
62 
63 LIBCOPP_COPP_API std::size_t stack_traits::page_size() LIBCOPP_MACRO_NOEXCEPT { return detail::pagesize(); }
64 
65 LIBCOPP_COPP_API std::size_t stack_traits::default_size() LIBCOPP_MACRO_NOEXCEPT {
66  std::size_t size = 8 * minimum_size(); // 64 KB
67  if (is_unbounded()) return size;
68 
69  assert(maximum_size() >= minimum_size());
70  return maximum_size() == size ? size : (std::min)(size, maximum_size());
71 }
72 
73 LIBCOPP_COPP_API std::size_t stack_traits::minimum_size() LIBCOPP_MACRO_NOEXCEPT { return MINSIGSTKSZ; }
74 
75 LIBCOPP_COPP_API std::size_t stack_traits::maximum_size() LIBCOPP_MACRO_NOEXCEPT {
76  if (is_unbounded()) return std::numeric_limits<std::size_t>::max();
77  return detail::stacksize_limit().rlim_max;
78 }
79 
80 LIBCOPP_COPP_API std::size_t stack_traits::round_to_page_size(std::size_t stacksize) LIBCOPP_MACRO_NOEXCEPT {
81  // page size must be 2^N
82  return static_cast<std::size_t>((stacksize + detail::pagesize() - 1) & (~(detail::pagesize() - 1)));
83 }
84 LIBCOPP_COPP_NAMESPACE_END
85 
86 # ifdef COPP_HAS_ABI_HEADERS
87 # include COPP_ABI_SUFFIX
88 # endif
89 
90 # ifdef UDEF_MINSIGSTKSZ
91 # undef MINSIGSTKSZ
92 # endif
93 
94 #endif
static rlimit stacksize_limit()
static rlimit stacksize_limit_()
static std::size_t pagesize()
constexpr auto size(TCONTAINER &&container) -> decltype(container.size())
Definition: span.h:44
#define MINSIGSTKSZ
static LIBCOPP_COPP_API std::size_t default_size() LIBCOPP_MACRO_NOEXCEPT
static LIBCOPP_COPP_API std::size_t page_size() LIBCOPP_MACRO_NOEXCEPT
static LIBCOPP_COPP_API std::size_t maximum_size() LIBCOPP_MACRO_NOEXCEPT
static LIBCOPP_COPP_API std::size_t round_to_page_size(std::size_t stacksize) LIBCOPP_MACRO_NOEXCEPT
static LIBCOPP_COPP_API std::size_t minimum_size() LIBCOPP_MACRO_NOEXCEPT
static LIBCOPP_COPP_API bool is_unbounded() LIBCOPP_MACRO_NOEXCEPT