libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
13extern "C" {
14#include <Windows.h>
15#include <assert.h>
16}
17
18#if defined(LIBCOPP_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 LIBCOPP_HAS_ABI_HEADERS
54# include LIBCOPP_ABI_PREFIX
55#endif
56
57LIBCOPP_COPP_NAMESPACE_BEGIN
58
59namespace detail {
60#if __cplusplus < 201103L
61static void system_info_(SYSTEM_INFO *si) { ::GetSystemInfo(si); }
62
63static 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
76static 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
85static 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
98LIBCOPP_COPP_API bool stack_traits::is_unbounded() LIBCOPP_MACRO_NOEXCEPT { return true; }
99
100LIBCOPP_COPP_API std::size_t stack_traits::page_size() LIBCOPP_MACRO_NOEXCEPT { return detail::pagesize(); }
101
102LIBCOPP_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
111LIBCOPP_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() )
115LIBCOPP_COPP_API std::size_t stack_traits::maximum_size() LIBCOPP_MACRO_NOEXCEPT {
116 assert(is_unbounded());
117 return SIZE_MAX;
118}
119
120LIBCOPP_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}
124LIBCOPP_COPP_NAMESPACE_END
125
126#ifdef LIBCOPP_HAS_ABI_HEADERS
127# include LIBCOPP_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