NUMA++ 0.12.0
Loading...
Searching...
No Matches
memory.hpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup numapp_mem
4 * @brief Contains memory function declarations.
5 * @copyright
6 * SPDX-FileCopyrightText: 2021-2025 European Southern Observatory (ESO)
7 *
8 * SPDX-License-Identifier: LGPL-3.0-only
9 *
10 * @defgroup numapp_mem_huge Huge Pages
11 * @ingroup numapp_mem
12 * @brief Utilities for allocating huge pages.
13 *
14 */
15#ifndef NUMAPP_MEMORY_HPP_
16#define NUMAPP_MEMORY_HPP_
17#include <numapp/config.hpp>
18
19#include <sys/mman.h>
20
21#include <cstddef>
22#include <memory_resource>
23#include <optional>
24#include <system_error>
25
26#include <numapp/flags.hpp>
27#include <numapp/mempolicy.hpp>
28#include <numapp/nodemask.hpp>
29
30namespace numapp {
31
32/**
33 * @name Hardware Queries
34 *
35 * Query host system/hardware.
36 * @ingroup numapp_mem
37 */
38// @{
39
40/**
41 * Fast query of system page size.
42 *
43 * @returns number of bytes in a page.
44 *
45 * @manpages
46 * @manpage{numa,3,@c numa_pagesize}
47 * @ingroup numapp_mem
48 */
49[[nodiscard]] std::size_t GetPageSize() noexcept;
50
51/**
52 * Query number of configured NUMA nodes.
53 *
54 * @returns number of configured NUMA nodes (this also includes any disabled nodes).
55 *
56 * @manpages
57 * @manpage{numa,3,@c numa_num_configured_nodes}
58 * @ingroup numapp_mem
59 */
60[[nodiscard]] int GetNumNodes() noexcept;
61
62/**
63 * Get NUMA distance between two nodes.
64 *
65 * A node has distance 10 to itself.
66 *
67 * @param node1 NUMA node number.
68 * @param node2 NUMA node number.
69 *
70 * @returns distance between @a node1 and @a node2.
71 * @returns @c std::nullopt when distance cannot be determined.
72 *
73 * @manpages
74 * @manpage{numa,3,@c numa_distance}
75 * @ingroup numapp_mem
76 */
77[[nodiscard]] std::optional<int> GetNodeDistance(int node1, int node2) noexcept;
78
79/**
80 * Get NUMA node of the given CPU
81 *
82 * @param cpu CPU to get the NUMA node for.
83 *
84 * @returns NUMA node.
85 * @returns @c std::nullopt if @a cpu is invalid.
86 *
87 * @manpages
88 * @manpage{numa,3,@c numa_node_of_cpu}
89 * @ingroup numapp_mem
90 */
91[[nodiscard]] std::optional<int> GetNodeOfCpu(int cpu) noexcept;
92// @}
93
94/**
95 * @name Memory Locking
96 *
97 * These functions provide the means to prevent memory from being paged to the swap area.
98 *
99 * @note Care should be taken when using these as resident memory consumption will increase as the
100 * risk of out-of-memory scenarios. In particular it should be noted that applications may allocate
101 * memory that is never resident in normal use. Forcing this memory to be faulted-in may lead to
102 * significant memory pressure. One way to avoid that is to use @c LockFlag::OnFault and
103 * @c LockAllFlag::OnFault which will lock resident memory only. _For real-time applications_ this
104 * should not be used however as page faults should be avoided in those scenarios.
105 *
106 * @par Permissions
107 *
108 * Locking may require additional permissions if it exceeds resource limits (\manpage{getrlimit,2}).
109 * Permissions can be provided by `CAP_IPC_LOCK` (\manpage{capabilities,7}).
110 *
111 * See also page section @ref memory-api-locking.
112 * @ingroup numapp_mem
113 */
114// @{
115
116/**
117 * Mutually exclusive flags that modifies behaviour of @ref MemLock().
118 *
119 * @ingroup numapp_mem
120 */
121enum class LockFlag : unsigned int {
122 /**
123 * Locks pages whether they are resident or not. After a successful call to MemLock access to
124 * the full range will not trigger page faults.
125 *
126 * @note Behaves like @c mlock().
127 */
129
130 /**
131 * Locks currently resident pages as well as future resident pages _when_ they are first faulted
132 * in.
133 */
134 OnFault = MLOCK_ONFAULT,
135};
136
137/**
138 * Flags that are combined to modify behaviour of @ref MemLockAll().
139 *
140 * LockAllFlag have the following operators defined in namespace numapp:
141 * - <tt>operator|(LockAllFlag, LockAllFlag)</tt>
142 * - <tt>operator=|(LockAllFlag&, LockAllFlag)</tt>
143 * - <tt>operator&(LockAllFlag, LockAllFlag)</tt>
144 * - <tt>operator=&(LockAllFlag&, LockAllFlag)</tt>
145 *
146 * @ingroup numapp_mem
147 */
148enum class LockAllFlag : int {
149 /**
150 * Lock all pages which are currently mapped into the address space of the process.
151 */
152 Current = MCL_CURRENT,
153
154 /**
155 * Lock all future pages that are mapped into the address space of the process.
156 */
157 Future = MCL_FUTURE,
158
159#if defined(MCL_ONFAULT) || defined(DOXYGEN)
160 /**
161 * OnFault must be used together with Current and/or Future and modifies the behaviour so pages
162 * are not locked until they are faulted in.
163 *
164 * @since Linux 4.4
165 */
166 OnFault = MCL_ONFAULT,
167#endif
168};
169
171
172/**
173 * Lock memory pages in the specified address range.
174 *
175 * To unlock memory use numapp::MemUnlock or numapp::MemUnlockAll.
176 *
177 * @note Locking memory can be used in conjunction with e.g. numapp::Allocate() to allocate memory
178 * and pre-fault it to guarantee that no page-faults happen on subsequent access.
179 *
180 * @code
181 * void* buffer = numapp::Allocate(size, policy);
182 * if (std::error_code ec = numapp::MemLock(buffer, size, numapp::LockFlag::PreFault); ec) {
183 * // Handle error
184 * }
185 * @endcode
186 *
187 * @param addr Defines the starting address of the range.
188 * @param len Defines the length of the address range.
189 * @param flag Behaviour modifier, see @ref LockFlag.
190 * @return error code populated with errno error.
191 *
192 * @manpages
193 * @manpage{mlock2,2}
194 * @ingroup numapp_mem
195 */
196[[nodiscard]] std::error_code MemLock(void const* addr, std::size_t len, LockFlag flag) noexcept;
197
198/**
199 * Unlock memory pages in the specified address range.
200 *
201 * @param addr Defines the starting address of the range.
202 * @param len Defines the length of the address range.
203 * @return error code populated with errno error.
204 *
205 * @manpages
206 * @manpage{munlock,2}
207 * @ingroup numapp_mem
208 */
209[[nodiscard]] std::error_code MemUnlock(void const* addr, std::size_t len) noexcept;
210
211/**
212 * Lock all memory pages as specified by provided flags.
213 *
214 * As an example this is how to lock current and future memory allocations:
215 * @code
216 *
217 * using namespace numapp; // Also brings in operator| into scope so that flags can be OR-ed.
218 *
219 * if (auto ec = MemLockAll(LockAllFlag::Current | LockAllFlag::Future); ec) {
220 * // Failed to lock...
221 * }
222 *
223 * @endcode
224 *
225 * To unlock memory use MemUnlock and MemUnlockAll.
226 *
227 * @warning If flag @c LockAllFlag::Future is used memory pages will be locked during
228 * mapping using the calling thread default memory policy. For numapp::Allocate() this means that
229 * pages may have to be moved after mapping (see also notes in numapp::Allocate()).
230 *
231 * @param flags Combination of @ref LockAllFlag values. See documentation of @ref LockAllFlag how it
232 * modifies the behaviour.
233 * @return error code populated with errno error.
234 *
235 * @manpages
236 * @manpage{mlockall,2}
237 * @ingroup numapp_mem
238 */
239[[nodiscard]] std::error_code MemLockAll(LockAllFlag flags) noexcept;
240
241/**
242 * Unlock all locked memory in this process.
243 *
244 * @return error code populated with errno error.
245 *
246 * @manpages
247 * @manpage{munlockall,2}
248 * @ingroup numapp_mem
249 */
250[[nodiscard]] std::error_code MemUnlockAll() noexcept;
251// @}
252
253/**
254 * @name Allocate and free memory with specified memory policy
255 *
256 * @anchor numapp_alloc
257 *
258 * @par Allocate
259 * numapp::Allocate() function is equivalent to performing the following:
260 * - Create new memory mapping with `mmap` (anonymous read/write) memory
261 * - Applying memory policy to allocated memory using provided @c policy and @c flag <sup>(1)</sup>
262 * using `mbind`.
263 *
264 * <sup>(1)</sup> Overloads without @c flag use no modifiers (i.e. won't move pages).
265 *
266 * @par Important
267 * Memory is not pre-faulted by default. If memory is used by real-time threads consider using
268 * numapp::MemLock() after allocation to guarantee that pages as faulted in.
269 *
270 * @par
271 * However if process locks memory when it is mapped (as controlled by numapp::MemLockAll() with
272 * @c numapp::LockAllFlag::Future) memory may have to be @a moved to apply the requested policy. It
273 * is in this case the @c flags argument has an important role to control if pages should be moved.
274 *
275 * @par Free
276 * numapp::Free() frees memory previously allocated with numapp::Allocate().
277 *
278 * @param [in] size Number of bytes to allocate/free, will be rounded up to multiples of system page
279 * size.
280 * @param [in] policy Memory policy to apply.
281 * @param [in] flags Controls behaviour if memory have to be moved because it was already paged-in
282 * due to a numapp::MemLockAll policy.
283 * @param [in] ptr Page-aligned pointer to memory previously allocated with numapp::Allocate().
284 * @param [out] ec Error code for non-throwing overloads. If there is an out of memory situation the
285 * error code @c std::errc::not_enough_memory is used.
286 *
287 * @throws std::system_error on failure (only applicable to throwing-overloads without
288 * @c std::error_code return value).
289 *
290 * @returns numapp::Allocate() returns pointer to memory block that is at least @a size big or @c
291 * nullptr on failure.
292 *
293 * Example allocating with bind policy and then lock and pre-fault the newly allocated memory:
294 *
295 * @include allocExample.cpp
296 *
297 * @manpages
298 * @manpage{mmap,2}
299 * @manpage{mbind,2}
300 * @ingroup numapp_mem
301 */
302/// @{
303
304// clang-format off
305/**
306 * @relatesalso MemPolicy
307 * See @ref numapp_alloc "group" for details.
308 * @ingroup numapp_mem */
309[[nodiscard]] void* Allocate(std::size_t size,
310 MemPolicy const& policy,
311 std::error_code& ec) noexcept;
312/**
313 * @relatesalso MemPolicy
314 * See @ref numapp_alloc "group" for details.
315 * @ingroup numapp_mem */
316[[nodiscard]] void* Allocate(std::size_t size,
317 MemPolicy const& policy,
318 MemPolicyFlag flags,
319 std::error_code& ec) noexcept;
320/**
321 * @relatesalso MemPolicy
322 * See @ref numapp_alloc "group" for details.
323 * @ingroup numapp_mem */
324[[nodiscard]] void* Allocate(std::size_t size,
325 MemPolicy const& policy);
326/**
327 * @relatesalso MemPolicy
328 * See @ref numapp_alloc "group" for details.
329 * @ingroup numapp_mem */
330[[nodiscard]] void* Allocate(std::size_t size,
331 MemPolicy const& policy,
332 MemPolicyFlag flags);
333// clang-format on
334/**
335 * @relatesalso MemPolicy
336 * See @ref numapp_alloc "group" for details.
337 * @ingroup numapp_mem */
338void Free(void* ptr, std::size_t size, std::error_code& ec) noexcept;
339
340/**
341 * @relatesalso MemPolicy
342 * See @ref numapp_alloc "group" for details.
343 * @ingroup numapp_mem */
344void Free(void* ptr, std::size_t size);
345/// @}
346
347/**
348 * Polymorphic memory resource allocating full system pages with specified NUMA policy. Memory is
349 * page-aligned and allocated size is rounded up to nearest full page.
350 *
351 * Allocations are performed using numapp::Allocate() and deallocations use numapp::Free(), see @ref
352 * numapp_alloc for details.
353 *
354 * @attention This is not a suitable general purpose memory resource as it is generally slow and
355 * always allocates full pages and should be considered to be a block allocator serving a higher
356 * level allocator that is aware of this, with blocks of memory.
357 *
358 * @ingroup numapp_mem
359 * @headerfile <> <numapp/memory.hpp>
360 */
361class PageResource : public std::pmr::memory_resource {
362public:
363 /**
364 * Create PageResource with specified memory policy and flags.
365 *
366 * @param policy Memory policy to use when allocating.
367 * @param flags Memory policy flags to use when allocating.
368 */
369 PageResource(MemPolicy policy, MemPolicyFlag flags = MemPolicyFlag::None);
370
371 /**
372 * Destroy PageResource.
373 */
374 virtual ~PageResource() = default;
375
376 /**
377 * Page resource is not copy assignable.
378 */
380
381 /**
382 * Get memory policy in use.
383 */
384 auto GetPolicy() const noexcept -> MemPolicy const&;
385
386 /**
387 * Get flags in use.
388 */
389 auto GetFlags() const noexcept -> MemPolicyFlag;
390
391private:
392 auto do_allocate(std::size_t bytes, std::size_t alignment) -> void* override;
393 void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override;
394 auto do_is_equal(std::pmr::memory_resource const& other) const noexcept -> bool override;
395
396 MemPolicy m_policy;
397 MemPolicyFlag m_flags;
398};
399
400/**
401 * Lock memory allocated from upstream memory resource using specified @ref LockFlag.
402 *
403 * @note If locking fails memory is deallocated and `std::system_error` exception is thrown.
404 *
405 * @ingroup numapp_mem
406 * @headerfile <> <numapp/memory.hpp>
407 */
408class LockResource : public std::pmr::memory_resource {
409public:
410 /**
411 * Initialize with specified flag and upstream memory resource initialized from
412 * `std::pmr::get_default_resource()`.
413 *
414 * @param flag Lock flag controlling memory locking behavior.
415 */
416 LockResource(LockFlag flag) noexcept;
417
418 /**
419 * Initialize with specified upstream memory resource using `LockFlag::PreFault`.
420 *
421 * @param upstream Upstream memory resource from where allocations are delegated; must point to
422 * valid memory resource.
423 */
424 LockResource(std::pmr::memory_resource* upstream) noexcept;
425
426 /**
427 * Initialize with specified lock flag and upstream memory resource.
428 *
429 * @param flag Lock flag controlling memory locking behavior.
430 * @param upstream Upstream memory resource from where allocations are delegated; must point to
431 * valid memory resource.
432 */
433 LockResource(LockFlag flag, std::pmr::memory_resource* upstream) noexcept;
434
435 /**
436 * Destroy LockResource.
437 */
438 virtual ~LockResource() = default;
439
440 /**
441 * LockResource is not copy assignable.
442 */
444
445 /**
446 * Get lock flag in use.
447 *
448 * @return Lock flags.
449 */
450 auto GetFlags() const noexcept -> LockFlag;
451
452 /**
453 * Get upstream memory resource.
454 *
455 * @return Upstream memory resoure.
456 */
457 auto GetUpstream() const noexcept -> std::pmr::memory_resource*;
458
459private:
460 auto do_allocate(std::size_t bytes, std::size_t alignment) -> void* override;
461 void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override;
462 auto do_is_equal(std::pmr::memory_resource const& other) const noexcept -> bool override;
463
464 std::pmr::memory_resource* m_upstream;
465 LockFlag m_flag;
466};
467
468/**
469 * Preset huge page sizes.
470 *
471 * Commonly supported sizes are
472 * - Huge2M and Huge1G on x86.
473 * - Huge8k, Huge64k, Huge256k, Huge1M, Huge4M, Huge16M, Huge256M on ia64.
474 * - Huge16M on ppc64.
475 *
476 * @ingroup numapp_mem_huge
477 */
478enum class HugePagePreset : std::size_t {
479 /**
480 * 8 KiB page size.
481 */
482 Huge8k = 8 * 1024,
483
484 /**
485 * 16 KiB page size.
486 */
487 Huge16k = 16 * 1024,
488
489 /**
490 * 64 kiB page size.
491 */
492 Huge64k = 64 * 1024,
493
494 /**
495 * 256 kiB page size.
496 */
497 Huge256k = 256 * 1024,
498
499 /**
500 * 1 MiB page size.
501 */
502 Huge1M = 1 * 1024 * 1024,
503
504 /**
505 * 2 MiB page size.
506 */
507 Huge2M = 2 * 1024 * 1024,
508
509 /**
510 * 4 MiB page size.
511 */
512 Huge4M = 4 * 1024 * 1024,
513
514 /**
515 * 16 MiB page size.
516 */
517 Huge16M = 16 * 1024 * 1024,
518
519 /**
520 * 256 MiB page size.
521 */
522 Huge256M = 256 * 1024 * 1024,
523
524 /**
525 * 1 GiB page size.
526 */
527 Huge1G = 1ul * 1024 * 1024 * 1024,
528};
529
530/**
531 * Describes a huge page size and maintains the invariant that page size is an integral power of 2,
532 * compatible with `mmap()` expectations.
533 *
534 * @ingroup numapp_mem_huge
535 */
537public:
538 /**
539 * Construct from preset page size value.
540 *
541 * @param preset page size preset.
542 */
543 HugePageSize(HugePagePreset preset) noexcept;
544
545 /**
546 * Construct with given page size.
547 *
548 * Provided size @a bytes must an integer power of two and its base-2 logarithm must not be 0.
549 *
550 * @param bytes Size in bytes.
551 *
552 * @throws std::invalid_argument if @a bytes is not an integer power of two or its base-2
553 * logarithm is 0.
554 */
555 explicit HugePageSize(std::size_t bytes);
556
557 /**
558 * Query size in bytes.
559 *
560 * @return Size in bytes, is always an integer power of two and its base-2 logarithm is > 0.
561 */
562 constexpr auto Size() const noexcept -> std::size_t;
563
564 /**
565 * Three-way comparison operator.
566 */
567 auto operator<=>(HugePageSize const&) const noexcept -> std::strong_ordering = default;
568
569private:
570 std::size_t m_size;
571};
572
573/**
574 * Encodes page size into bit representation expected by `mmap()`.
575 *
576 * @return Page size encoded as `mmap()` flags.
577 *
578 * @manpages
579 * @manpage{mmap,2}
580 * @ingroup numapp_mem_huge
581 */
582auto EncodeMmapFlags(HugePageSize page_size) noexcept -> int;
583
584/**
585 * @name Allocate and free huge pages
586 *
587 * @anchor numapp_alloc_huge
588 *
589 * Allocation is similar to @ref numapp_alloc "Allocate and free" but with the additional argument
590 * specifying the (huge) page size. Like non-huge allocations the pages are not pre-faulted by the
591 * functions so to avoid page fault failurs it is recommended to do that before use.
592 *
593 * @include allocHugeExample.cpp
594 *
595 * @par Parameters
596 * @param [in] size Number of bytes to allocate/free, will be rounded up to multiples of @a
597 * page_size.
598 * @param [in] page_size Page size.
599 * @param [in] policy Memory policy to apply.
600 * @param [in] flags Controls behaviour if memory have to be moved because it was already paged-in
601 * due to a numapp::MemLockAll policy.
602 * @param [in] ptr Page-aligned pointer to memory previously allocated with numapp::AllocateHuge().
603 * @param [out] ec Error code for non-throwing overloads. If there is an out of memory situation the
604 * error code @c std::errc::not_enough_memory is used.
605 *
606 * @throws std::system_error on failure (only applicable to throwing-overloads without
607 * @c std::error_code return value).
608 *
609 * @returns numapp::AllocateHuge() returns pointer to memory block that is at least @a size big or
610 * @c nullptr on failure.
611 * @manpages
612 * @manpage{mmap,2}
613 * @manpage{mbind,2}
614 */
615// @{
616/**
617 * Non-throwing version of AllocateHuge()
618 *
619 * See @ref numapp_alloc_huge "Allocate and free huge pages" for details.
620 *
621 * @relatesalso MemPolicy
622 * @ingroup numapp_mem_huge
623 */
624[[nodiscard]] void* AllocateHuge(std::size_t size,
625 HugePageSize page_size,
626 MemPolicy const& policy,
627 MemPolicyFlag flags,
628 std::error_code& ec) noexcept;
629
630/**
631 * Throwing version of AllocateHuge()
632 *
633 * See @ref numapp_alloc_huge "Allocate and free huge pages" for details.
634 *
635 * @relatesalso MemPolicy
636 * @ingroup numapp_mem_huge
637 */
638[[nodiscard]] void* AllocateHuge(std::size_t size,
639 HugePageSize page_size,
640 MemPolicy const& policy,
641 MemPolicyFlag flags);
642
643/**
644 * Free huge pages previously allocated with AllocateHuge.
645 *
646 * @note Behaviour is unspecified if @a ptr, @a size and @a page_size are different than from
647 * previous call to AllocateHuge().
648 *
649 * @note page_size is needed because munmap requires that sz in munmap(ptr, sz) is a multiple of
650 * page size, which is not the case for system pages.
651 *
652 * See @ref numapp_alloc_huge "Allocate and free huge pages" for details.
653 *
654 * @ingroup numapp_mem_huge
655 */
656void FreeHuge(void* ptr, std::size_t size, HugePageSize page_size, std::error_code& ec) noexcept;
657
658/**
659 * Throwing version of `FreeHuge()`.
660 *
661 * See @ref numapp_alloc_huge "Allocate and free huge pages" for details.
662 *
663 * @throws std::system_error on errors.
664 */
665void FreeHuge(void* ptr, std::size_t size, HugePageSize page_size);
666// @}
667
668/**
669 * Polymorphic memory resource allocating huge pages with specified NUMA policy. Memory is
670 * page-aligned and allocated size is rounded up to nearest full page.
671 *
672 * Allocations are performed using numapp::AllocateHuge() and deallocations use numapp::FreeHuge(),
673 * see @ref numapp_alloc_huge for details.
674 *
675 * @attention This is not a suitable general purpose memory resource as it is generally slow and
676 * always allocates full pages and should be considered to be a block allocator serving a higher
677 * level allocator that is aware of this, with blocks of memory.
678 *
679 * @ingroup numapp_mem_huge
680 * @headerfile <> <numapp/memory.hpp>
681 */
682class HugePageResource : public std::pmr::memory_resource {
683public:
684 /**
685 * Create PageResource with specified memory policy and flags.
686 *
687 * @param page_size Page size to use when allocating.
688 * @param policy Memory policy to use when allocating.
689 * @param flags Memory policy flags to use when allocating.
690 */
692 MemPolicy policy,
693 MemPolicyFlag flags = MemPolicyFlag::None);
694
695 /**
696 * Destroy PageResource.
697 */
698 virtual ~HugePageResource() = default;
699
700 /**
701 * HugePage resource is not copy assignable.
702 */
704
705 /**
706 * Get memory policy in use.
707 */
708 auto GetPolicy() const noexcept -> MemPolicy const&;
709
710 /**
711 * Get flags in use.
712 */
713 auto GetFlags() const noexcept -> MemPolicyFlag;
714
715 /**
716 * Get page size.
717 */
718 auto GetPageSize() const noexcept -> HugePageSize;
719
720private:
721 auto do_allocate(std::size_t bytes, std::size_t alignment) -> void* override;
722 void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override;
723 auto do_is_equal(std::pmr::memory_resource const& other) const noexcept -> bool override;
724
725 HugePageSize m_page_size;
726 MemPolicy m_policy;
727 MemPolicyFlag m_flags;
728};
729
730constexpr auto HugePageSize::Size() const noexcept -> std::size_t {
731 return m_size;
732}
733
734} // namespace numapp
735#endif // #ifndef NUMAPP_MEMORY_HPP_
HugePageResource & operator=(HugePageResource const &)=delete
HugePage resource is not copy assignable.
auto GetPageSize() const noexcept -> HugePageSize
Get page size.
Definition memory.cpp:264
HugePageResource(HugePageSize page_size, MemPolicy policy, MemPolicyFlag flags=MemPolicyFlag::None)
Create PageResource with specified memory policy and flags.
Definition memory.cpp:252
auto GetFlags() const noexcept -> MemPolicyFlag
Get flags in use.
Definition memory.cpp:260
auto GetPolicy() const noexcept -> MemPolicy const &
Get memory policy in use.
Definition memory.cpp:256
virtual ~HugePageResource()=default
Destroy PageResource.
Describes a huge page size and maintains the invariant that page size is an integral power of 2,...
Definition memory.hpp:536
constexpr auto Size() const noexcept -> std::size_t
Query size in bytes.
Definition memory.hpp:730
HugePageSize(HugePagePreset preset) noexcept
Construct from preset page size value.
Definition memory.cpp:147
auto operator<=>(HugePageSize const &) const noexcept -> std::strong_ordering=default
Three-way comparison operator.
LockResource & operator=(LockResource const &)=delete
LockResource is not copy assignable.
virtual ~LockResource()=default
Destroy LockResource.
LockResource(LockFlag flag) noexcept
Initialize with specified flag and upstream memory resource initialized from std::pmr::get_default_re...
Definition memory.cpp:284
auto GetUpstream() const noexcept -> std::pmr::memory_resource *
Get upstream memory resource.
Definition memory.cpp:324
auto GetFlags() const noexcept -> LockFlag
Get lock flag in use.
Definition memory.cpp:320
Class representing a memory policy that can be modified and used to apply to the current thread or a ...
PageResource & operator=(PageResource const &)=delete
Page resource is not copy assignable.
auto GetFlags() const noexcept -> MemPolicyFlag
Get flags in use.
Definition memory.cpp:233
virtual ~PageResource()=default
Destroy PageResource.
PageResource(MemPolicy policy, MemPolicyFlag flags=MemPolicyFlag::None)
Create PageResource with specified memory policy and flags.
Definition memory.cpp:225
auto GetPolicy() const noexcept -> MemPolicy const &
Get memory policy in use.
Definition memory.cpp:229
NUMA++ configuration.
Contains definitions for bitwise operators for enums.
#define NUMAPP_ENABLE_BITFLAG(enum)
Enables numapp bitwise operators in overload set for the specified enumeration enum.
Definition flags.hpp:19
void FreeHuge(void *ptr, std::size_t size, HugePageSize page_size, std::error_code &ec) noexcept
Free huge pages previously allocated with AllocateHuge.
Definition memory.cpp:207
auto EncodeMmapFlags(HugePageSize page_size) noexcept -> int
Encodes page size into bit representation expected by mmap().
Definition memory.cpp:162
HugePagePreset
Preset huge page sizes.
Definition memory.hpp:478
void * AllocateHuge(std::size_t size, HugePageSize page_size, MemPolicy const &policy, MemPolicyFlag flags, std::error_code &ec) noexcept
Non-throwing version of AllocateHuge()
Definition memory.cpp:167
@ Huge8k
8 KiB page size.
Definition memory.hpp:482
@ Huge2M
2 MiB page size.
Definition memory.hpp:507
@ Huge4M
4 MiB page size.
Definition memory.hpp:512
@ Huge1G
1 GiB page size.
Definition memory.hpp:527
@ Huge64k
64 kiB page size.
Definition memory.hpp:492
@ Huge16k
16 KiB page size.
Definition memory.hpp:487
@ Huge1M
1 MiB page size.
Definition memory.hpp:502
@ Huge16M
16 MiB page size.
Definition memory.hpp:517
@ Huge256k
256 kiB page size.
Definition memory.hpp:497
@ Huge256M
256 MiB page size.
Definition memory.hpp:522
int GetNumNodes() noexcept
Query number of configured NUMA nodes.
Definition memory.cpp:46
std::error_code MemLock(void const *addr, std::size_t len, LockFlag flag) noexcept
Lock memory pages in the specified address range.
Definition memory.cpp:60
std::size_t GetPageSize() noexcept
Fast query of system page size.
Definition memory.cpp:42
LockAllFlag
Flags that are combined to modify behaviour of MemLockAll().
Definition memory.hpp:148
std::error_code MemUnlock(void const *addr, std::size_t len) noexcept
Unlock memory pages in the specified address range.
Definition memory.cpp:67
std::optional< int > GetNodeDistance(int node1, int node2) noexcept
Get NUMA distance between two nodes.
Definition memory.cpp:50
void Free(void *ptr, std::size_t size, std::error_code &ec) noexcept
See group for details.
Definition memory.cpp:131
LockFlag
Mutually exclusive flags that modifies behaviour of MemLock().
Definition memory.hpp:121
void * Allocate(std::size_t size, MemPolicy const &policy, std::error_code &ec) noexcept
See group for details.
Definition memory.cpp:89
std::error_code MemUnlockAll() noexcept
Unlock all locked memory in this process.
Definition memory.cpp:81
std::error_code MemLockAll(LockAllFlag flags) noexcept
Lock all memory pages as specified by provided flags.
Definition memory.cpp:74
std::optional< int > GetNodeOfCpu(int cpu) noexcept
Get NUMA node of the given CPU.
Definition memory.cpp:55
@ Current
Lock all pages which are currently mapped into the address space of the process.
Definition memory.hpp:152
@ Future
Lock all future pages that are mapped into the address space of the process.
Definition memory.hpp:157
@ PreFault
Locks pages whether they are resident or not.
Definition memory.hpp:128
@ OnFault
Locks currently resident pages as well as future resident pages when they are first faulted in.
Definition memory.hpp:134
Contains declarations for numapp::MemPolicy.
Contains declarations for Nodemask.