HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
locked_memory_allocator_win32_impl.hpp
1// Copyright Take Vos 2021-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
8
9#include "locked_memory_allocator_intf.hpp"
10#include "../telemetry/telemetry.hpp"
11#include "../char_maps/char_maps.hpp" // XXX #616
12#include "../utility/utility.hpp"
13#include "../macros.hpp"
14#include <cstddef>
15#include <format>
16#include <type_traits>
17#include <string_view>
18#include <string>
19#include <compare>
20#include <exception>
21#include <chrono> // XXX #620
22
23hi_export_module(hikogui.memory.locked_memory_allocator : impl);
24
25hi_export namespace hi::inline v1 {
26
27[[nodiscard]] inline std::byte *locked_memory_allocator_allocate(std::size_t n) noexcept
28{
29 auto p = VirtualAlloc(NULL, n, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
30 if (p == NULL) {
31 hi_log_fatal("Could not allocate locked memory. '{}'", get_last_error_message());
32 }
33
34 auto handle = GetCurrentProcess();
35 SIZE_T minimum_working_set_size;
36 SIZE_T maximum_working_set_size;
37
38 if (!GetProcessWorkingSetSize(handle, &minimum_working_set_size, &maximum_working_set_size)) {
39 hi_log_warning("Could not get process working set size. '{}'", get_last_error_message());
40
41 } else {
42 minimum_working_set_size += ceil(n, SIZE_T{4096});
43 maximum_working_set_size += ceil(n, SIZE_T{4096});
44 if (!SetProcessWorkingSetSize(handle, minimum_working_set_size, maximum_working_set_size)) {
45 hi_log_warning(
46 "Could not set process working set size to {}:{}. '{}'",
47 minimum_working_set_size,
48 maximum_working_set_size,
50
51 } else {
52 if (!VirtualLock(p, n)) {
53 hi_log_warning("Could not lock memory. '{}'", get_last_error_message());
54 }
55 }
56 }
57 return static_cast<std::byte *>(p);
58}
59
60inline void locked_memory_allocator_deallocate(std::byte *p, std::size_t n) noexcept
61{
62 if (not VirtualUnlock(p, n)) {
63 hi_log_warning("Could not unlock memory. '{}'", get_last_error_message());
64
65 } else {
66 auto handle = GetCurrentProcess();
67 SIZE_T minimum_working_set_size;
68 SIZE_T maximum_working_set_size;
69
70 if (!GetProcessWorkingSetSize(handle, &minimum_working_set_size, &maximum_working_set_size)) {
71 hi_log_warning("Could not get process working set size. '{}'", get_last_error_message());
72
73 } else {
74 minimum_working_set_size -= ceil(n, SIZE_T{4096});
75 maximum_working_set_size -= ceil(n, SIZE_T{4096});
76 if (!SetProcessWorkingSetSize(handle, minimum_working_set_size, maximum_working_set_size)) {
77 hi_log_warning(
78 "Could not set process working set size to {}:{}. '{}'",
79 minimum_working_set_size,
80 maximum_working_set_size,
82 }
83 }
84 }
85
86 if (not VirtualFree(p, 0, MEM_RELEASE)) {
87 hi_log_fatal("Could not deallocate locked memory. '{}'", get_last_error_message());
88 }
89}
90
91} // namespace hi::inline v1
Rules for working with win32 headers.
hi_export std::string get_last_error_message()
Get the OS error message from the last error received on this thread.
Definition exception_win32_impl.hpp:30
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
T ceil(T... args)