libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
12extern "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 LIBCOPP_HAS_ABI_HEADERS
32# include LIBCOPP_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
38LIBCOPP_COPP_NAMESPACE_BEGIN
39
40namespace detail {
41static std::size_t pagesize() {
42 std::size_t size = static_cast<size_t>(::sysconf(_SC_PAGESIZE));
43 return size;
44}
45
46static rlimit stacksize_limit_() {
47 rlimit limit;
48 // conforming to POSIX.1-2001
49 ::getrlimit(RLIMIT_STACK, &limit);
50 return limit;
51}
52
53static rlimit stacksize_limit() {
54 static rlimit limit = stacksize_limit_();
55 return limit;
56}
57} // namespace detail
58
59LIBCOPP_COPP_API bool stack_traits::is_unbounded() LIBCOPP_MACRO_NOEXCEPT {
60 return RLIM_INFINITY == detail::stacksize_limit().rlim_max;
61}
62
63LIBCOPP_COPP_API std::size_t stack_traits::page_size() LIBCOPP_MACRO_NOEXCEPT { return detail::pagesize(); }
64
65LIBCOPP_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
73LIBCOPP_COPP_API std::size_t stack_traits::minimum_size() LIBCOPP_MACRO_NOEXCEPT {
74 return static_cast<size_t>(MINSIGSTKSZ);
75}
76
77LIBCOPP_COPP_API std::size_t stack_traits::maximum_size() LIBCOPP_MACRO_NOEXCEPT {
78 if (is_unbounded()) return std::numeric_limits<std::size_t>::max();
79 return detail::stacksize_limit().rlim_max;
80}
81
82LIBCOPP_COPP_API std::size_t stack_traits::round_to_page_size(std::size_t stacksize) LIBCOPP_MACRO_NOEXCEPT {
83 // page size must be 2^N
84 return static_cast<std::size_t>((stacksize + detail::pagesize() - 1) & (~(detail::pagesize() - 1)));
85}
86LIBCOPP_COPP_NAMESPACE_END
87
88# ifdef LIBCOPP_HAS_ABI_HEADERS
89# include LIBCOPP_ABI_SUFFIX
90# endif
91
92# ifdef UDEF_MINSIGSTKSZ
93# undef MINSIGSTKSZ
94# endif
95
96#endif
static rlimit stacksize_limit()
static rlimit stacksize_limit_()
static std::size_t pagesize()
#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