NUMA++ 0.12.0
Loading...
Searching...
No Matches
mempolicy.cpp
1/**
2 * @cond Impl
3 * @file
4 * @brief Definition of memory policy classes.
5 * @copyright
6 * SPDX-FileCopyrightText: 2020-2023 European Southern Observatory (ESO)
7 *
8 * SPDX-License-Identifier: LGPL-3.0-only
9 */
10#include <numapp/mempolicy.hpp>
11
12#include <iostream>
13
14#include <numapp/lowlevel.hpp>
15
16namespace numapp {
17namespace thisThread {
18std::error_code Apply(MemPolicy const& policy) noexcept {
19 if (auto err = ll::SetMemPolicy(static_cast<int>(policy.GetMode()), policy.GetNodemask());
20 err) {
21 return err;
22 } else {
23 return {};
24 }
25}
26
27std::error_code ApplyStack(MemPolicy const& policy, MemPolicyFlag flags) noexcept {
28 pthread_attr_t attr;
29 void* stack_addr = nullptr;
30 std::size_t stack_size = 0;
31 if (auto err = pthread_getattr_np(pthread_self(), &attr); err != 0) {
32 return std::make_error_code(static_cast<std::errc>(err));
33 }
34 if (auto err = pthread_attr_getstack(&attr, &stack_addr, &stack_size); err != 0) {
35 return std::make_error_code(static_cast<std::errc>(err));
36 }
37 return ::numapp::Apply(stack_addr, stack_size, policy, flags);
38}
39
40} // namespace thisThread
41
42std::error_code Apply(void* address,
43 std::size_t length,
44 MemPolicy const& policy,
45 MemPolicyFlag flags) NUMAPP_NOEXCEPT {
46 return ll::SetMemPolicy(address,
47 length,
48 static_cast<int>(policy.GetMode()),
49 policy.GetNodemask(),
50 static_cast<std::underlying_type<MemPolicyFlag>::type>(flags));
51}
52
54 auto node_mask = Nodemask();
55 // setbit does not return error if node is greater than node mask
56 (void)numa_bitmask_setbit(node_mask.GetNative(), node);
57 // So verify that bit is set and throw otherwise
58 if (!numa_bitmask_isbitset(node_mask.GetNative(), node)) {
59 throw std::system_error(std::make_error_code(std::errc::invalid_argument));
60 }
61
62 return MemPolicy(Mode::Bind, std::move(node_mask));
63}
64
66 int mode = 0;
67 Nodemask mask;
68 if (auto err = ll::GetMemPolicy(mode, mask, nullptr, 0); err) {
69 throw std::system_error(err);
70 }
71 return MemPolicy(static_cast<Mode>(mode), std::move(mask));
72}
73
75 int mode = 0;
76 Nodemask mask;
77 if (auto err = ll::GetMemPolicy(mode, mask, address, MPOL_F_ADDR); err) {
78 throw std::system_error(err);
79 }
80 return MemPolicy(static_cast<Mode>(mode), std::move(mask));
81}
82
83[[nodiscard]] std::error_code ScopedMemPolicy::Restore() noexcept {
84 if (m_old_policy) {
85 return thisThread::Apply(*m_old_policy);
86 }
87 return {};
88}
89
90std::ostream& operator<<(std::ostream& os, MemPolicy::Mode const& mode) {
91 switch (mode) {
93 os << "Default";
94 break;
96 os << "Bind";
97 break;
99 os << "Interleave";
100 break;
102 os << "Preferred";
103 break;
104 };
105 return os;
106}
107
108std::ostream& operator<<(std::ostream& os, MemPolicy const& mempolicy) {
109 os << "MemPolicy {mode=" << mempolicy.GetMode() << ", mask=" << mempolicy.GetNodemask() << "}";
110 return os;
111}
112} // namespace numapp
113/// @endcond Impl
Class representing a memory policy that can be modified and used to apply to the current thread or a ...
Mode
Memory allocation modes.
@ Bind
The Bind mode defines a strict policy that restricts memory allocation to the nodes specified in node...
@ Default
The Default mode specifies that any nondefault process memory policy be removed, so that the memory p...
@ Preferred
Preferred sets the preferred node for allocation.
@ Interleave
Interleave interleaves page allocations across the nodes specified in nodemask in numeric node ID ord...
MemPolicy(Mode mode, Nodemask &&node_mask) noexcept
Create memory policy.
static MemPolicy MakeFromActive()
Make from active default policy of calling thread.
static MemPolicy MakeFromAddress(void *address)
Make from policy at address.
static MemPolicy MakeBindNode(int node)
Creates a strict policy (using MPOL_BIND) to allocate all memory to the specified node.
std::error_code Restore() noexcept
Restores memory policy that was read during construction.
std::error_code Apply(CpuAffinity const &affinity) noexcept
Apply policy to calling thread.
std::error_code Apply(pid_t thread, CpuAffinity const &affinity) noexcept
Apply policy to specified thread.
std::error_code ApplyStack(MemPolicy const &policy, MemPolicyFlag flags=MemPolicyFlag::Move|MemPolicyFlag::Strict) noexcept
Convenience function that applies a memory policy to current thread stack memory.
Contains low-level functions.
Contains declarations for numapp::MemPolicy.
std::error_code SetMemPolicy(int mode, Nodemask const &mask) noexcept
Set active memory policy for calling thread.
std::error_code GetMemPolicy(int &mode, Nodemask &mask, void *addr, unsigned flags) noexcept
Get memory policy for calling thread or an address.