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