libcopp  2.2.0
stack_allocator_windows.cpp
Go to the documentation of this file.
1 // Copyright 2023 owent
2 
3 #include <libcopp/utils/config/libcopp_build_features.h>
4 
8 
9 #ifndef WIN32_LEAN_AND_MEAN
10 # define WIN32_LEAN_AND_MEAN
11 #endif
12 
13 extern "C" {
14 #include <Windows.h>
15 }
16 
17 // clang-format off
18 #include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
19 // clang-format on
20 #include <assert.h>
21 #include <algorithm>
22 #include <cstring>
23 #include <limits>
24 #include <numeric>
25 // clang-format off
26 #include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
27 // clang-format on
28 
29 #if defined(COPP_MACRO_COMPILER_MSVC)
30 # pragma warning(push)
31 # pragma warning(disable : 4244 4267)
32 #endif
33 
34 #ifdef COPP_HAS_ABI_HEADERS
35 # include COPP_ABI_PREFIX
36 #endif
37 
38 LIBCOPP_COPP_NAMESPACE_BEGIN
39 namespace allocator {
40 
41 LIBCOPP_COPP_API stack_allocator_windows::stack_allocator_windows() LIBCOPP_MACRO_NOEXCEPT {}
44  LIBCOPP_MACRO_NOEXCEPT {}
46  LIBCOPP_MACRO_NOEXCEPT {
47  return *this;
48 }
49 
50 LIBCOPP_COPP_API stack_allocator_windows::stack_allocator_windows(stack_allocator_windows &&) LIBCOPP_MACRO_NOEXCEPT {}
52  LIBCOPP_MACRO_NOEXCEPT {
53  return *this;
54 }
55 
56 LIBCOPP_COPP_API void stack_allocator_windows::allocate(stack_context &ctx, std::size_t size) LIBCOPP_MACRO_NOEXCEPT {
57  size = (std::max)(size, stack_traits::minimum_size());
59 
61  assert(size > 0 && size_ > 0);
62 
63  void *start_ptr = ::VirtualAlloc(0, size_, MEM_COMMIT, PAGE_READWRITE);
64  if (!start_ptr) {
65  ctx.sp = nullptr;
66  return;
67  }
68 
69  // memset(start_ptr, 0, size_);
70  DWORD old_options;
71  ::VirtualProtect(start_ptr, stack_traits::page_size(), PAGE_READWRITE | PAGE_GUARD, &old_options);
72 
73  ctx.size = size_;
74  ctx.sp = static_cast<char *>(start_ptr) + ctx.size; // stack down
75 }
76 
77 LIBCOPP_COPP_API void stack_allocator_windows::deallocate(stack_context &ctx) LIBCOPP_MACRO_NOEXCEPT {
78  assert(ctx.sp);
79  assert(stack_traits::minimum_size() <= ctx.size);
80  assert(stack_traits::is_unbounded() || (stack_traits::maximum_size() >= ctx.size));
81 
82  void *start_ptr = static_cast<char *>(ctx.sp) - ctx.size;
83  ::VirtualFree(start_ptr, 0, MEM_RELEASE);
84 }
85 } // namespace allocator
86 LIBCOPP_COPP_NAMESPACE_END
87 
88 #ifdef COPP_HAS_ABI_HEADERS
89 # include COPP_ABI_SUFFIX
90 #endif
memory allocator this allocator will create buffer using windows api and protect it
void deallocate(stack_context &) LIBCOPP_MACRO_NOEXCEPT
void allocate(stack_context &, std::size_t) LIBCOPP_MACRO_NOEXCEPT
stack_allocator_windows & operator=(const stack_allocator_windows &other) LIBCOPP_MACRO_NOEXCEPT
stack_allocator_windows() LIBCOPP_MACRO_NOEXCEPT
constexpr auto size(TCONTAINER &&container) -> decltype(container.size())
Definition: span.h:44
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