libcopp  2.2.0
stack_traits_windows.cpp
Go to the documentation of this file.
1 // Copyright 2023 owent
2 
3 #include <libcopp/utils/config/libcopp_build_features.h>
4 
5 #ifndef WIN32_LEAN_AND_MEAN
6 # define WIN32_LEAN_AND_MEAN
7 #endif
8 
9 // clang-format off
10 #include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
11 // clang-format on
12 
13 extern "C" {
14 #include <Windows.h>
15 #include <assert.h>
16 }
17 
18 #if defined(COPP_MACRO_COMPILER_MSVC)
19 # pragma warning(push)
20 # pragma warning(disable : 4244 4267)
21 #endif
22 
23 #include <algorithm>
24 #include <cmath>
25 #include <cstddef>
26 #include <cstring>
27 #include <stdexcept>
28 
29 #if __cplusplus >= 201103L
30 # include <mutex>
31 # include <thread>
32 #endif
33 // clang-format off
34 #include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
35 // clang-format on
36 
39 
40 // x86_64
41 // test x86_64 before i386 because icc might
42 // define __i686__ for x86_64 too
43 #if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(_M_X64) || \
44  defined(_M_AMD64)
45 
46 // Windows seams not to provide a constant or function
47 // telling the minimal stacksize
48 # define MIN_STACKSIZE 8 * 1024
49 #else
50 # define MIN_STACKSIZE 4 * 1024
51 #endif
52 
53 #ifdef COPP_HAS_ABI_HEADERS
54 # include COPP_ABI_PREFIX
55 #endif
56 
57 LIBCOPP_COPP_NAMESPACE_BEGIN
58 
59 namespace detail {
60 #if __cplusplus < 201103L
61 static void system_info_(SYSTEM_INFO *si) { ::GetSystemInfo(si); }
62 
63 static SYSTEM_INFO system_info() {
64  static SYSTEM_INFO si;
65  static bool inited = false;
66  if (inited) {
67  return si;
68  }
69 
70  system_info_(&si);
71  inited = true;
72  return si;
73 }
74 #else
75 
76 static SYSTEM_INFO system_info() {
77  static SYSTEM_INFO si;
78  static std::once_flag flag;
79  std::call_once(flag, []() { ::GetSystemInfo(&si); });
80  return si;
81 }
82 
83 #endif
84 
85 static std::size_t pagesize() { return static_cast<std::size_t>(system_info().dwPageSize); }
86 
94 } // namespace detail
95 
96 // Windows seams not to provide a limit for the stacksize
97 // libcoco uses 32k+4k bytes as minimum
98 LIBCOPP_COPP_API bool stack_traits::is_unbounded() LIBCOPP_MACRO_NOEXCEPT { return true; }
99 
100 LIBCOPP_COPP_API std::size_t stack_traits::page_size() LIBCOPP_MACRO_NOEXCEPT { return detail::pagesize(); }
101 
102 LIBCOPP_COPP_API std::size_t stack_traits::default_size() LIBCOPP_MACRO_NOEXCEPT {
103  std::size_t size = 64 * 1024; // 64 KB
104  if (is_unbounded()) return (std::max)(size, minimum_size());
105 
106  assert(is_unbounded() || maximum_size() >= minimum_size());
107  return is_unbounded() ? size : (std::min)(size, maximum_size());
108 }
109 
110 // because Windows seams not to provide a limit for minimum stacksize
111 LIBCOPP_COPP_API std::size_t stack_traits::minimum_size() LIBCOPP_MACRO_NOEXCEPT { return MIN_STACKSIZE; }
112 
113 // because Windows seams not to provide a limit for maximum stacksize
114 // maximum_size() can never be called (pre-condition ! is_unbounded() )
115 LIBCOPP_COPP_API std::size_t stack_traits::maximum_size() LIBCOPP_MACRO_NOEXCEPT {
116  assert(is_unbounded());
117  return SIZE_MAX;
118 }
119 
120 LIBCOPP_COPP_API std::size_t stack_traits::round_to_page_size(std::size_t stacksize) LIBCOPP_MACRO_NOEXCEPT {
121  // page size must be 2^N
122  return static_cast<std::size_t>((stacksize + stack_traits::page_size() - 1) & (~(stack_traits::page_size() - 1)));
123 }
124 LIBCOPP_COPP_NAMESPACE_END
125 
126 #ifdef COPP_HAS_ABI_HEADERS
127 # include COPP_ABI_SUFFIX
128 #endif
static void system_info_(SYSTEM_INFO *si)
static std::size_t pagesize()
static SYSTEM_INFO system_info()
constexpr auto size(TCONTAINER &&container) -> decltype(container.size())
Definition: span.h:44
#define MIN_STACKSIZE
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