#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct MappedMemoryConfiguration
{
#[serde(default)] pub address_hint: AddressHint,
#[serde(default)] pub protection: Protection,
#[serde(default)] pub sharing: Sharing,
#[serde(default)] pub page_size_preference: PageSizePreference,
#[serde(default = "MappedMemoryConfiguration::prefault_default")] pub prefault: bool,
#[serde(default)] pub reserve_swap_space: bool,
#[serde(default)] pub numa_memory_policy: Option<(SetMemoryPolicy, SetMemoryPolicyStrictness)>,
#[serde(default = "MappedMemoryConfiguration::lock_default")] pub lock: Option<MemoryLockSettings>,
#[serde(default = "MappedMemoryConfiguration::advice_default")] pub advice: HashSet<MemoryAdvice>,
}
impl Default for MappedMemoryConfiguration
{
#[inline(always)]
fn default() -> Self
{
Self
{
address_hint: AddressHint::default(),
protection: Protection::default(),
sharing: Sharing::default(),
page_size_preference: PageSizePreference::default(),
prefault: Self::prefault_default(),
reserve_swap_space: false,
numa_memory_policy: None,
lock: Self::lock_default(),
advice: Self::advice_default(),
}
}
}
impl MappedMemoryConfiguration
{
#[inline(always)]
pub fn into_settings(self, defaults: &DefaultHugePageSizes) -> MappedMemorySettings
{
MappedMemorySettings::new(self, defaults)
}
#[inline(always)]
fn anonymous_memory_map(&self, length: NonZeroU64, page_size_or_huge_page_size_settings: &PageSizeOrHugePageSizeSettings) -> Result<MappedMemory, MemoryMapError>
{
let mapped_memory = MappedMemory::anonymous(length, self.address_hint, self.protection, self.sharing, self.prefault, self.reserve_swap_space, page_size_or_huge_page_size_settings)?;
self.configure(mapped_memory)
}
#[inline(always)]
fn from_file_memory_map<F: MemoryMappableFileDescriptor>(&self, file_descriptor: &F, offset: u64, length: NonZeroU64, page_size_or_huge_page_size_settings: &PageSizeOrHugePageSizeSettings) -> Result<MappedMemory, MemoryMapError>
{
let mapped_memory = MappedMemory::from_file(file_descriptor, offset, length, self.address_hint, self.protection, self.sharing, self.prefault, self.reserve_swap_space, page_size_or_huge_page_size_settings)?;
self.configure(mapped_memory)
}
#[inline(always)]
fn configure(&self, mapped_memory: MappedMemory) -> Result<MappedMemory, MemoryMapError>
{
use self::MemoryMapError::*;
if let Some((set_memory_policy, set_memory_policy_strictness)) = self.numa_memory_policy.as_ref()
{
set_memory_policy_strictness.set_memory_address_policy(set_memory_policy, mapped_memory.virtual_address().into(), mapped_memory.mapped_size_in_bytes()).map_err(|_: ()| CouldNotSetNumaMemoryPolicy)?
}
if let Some(lock) = self.lock
{
let all_locked = mapped_memory.lock(lock).map_err(|cause| CouldNotLockMemory(cause, lock))?;
if !all_locked
{
return Err(CouldNotLockAllMappedMemory)
}
}
for &advice in self.advice.iter()
{
loop
{
let succeeded = mapped_memory.advise(advice).map_err(|cause| CouldNotApplyMemoryAdvice(cause, advice))?;
if likely!(succeeded)
{
break
}
}
}
Ok(mapped_memory)
}
#[inline(always)]
const fn prefault_default() -> bool
{
true
}
#[inline(always)]
const fn lock_default() -> Option<MemoryLockSettings>
{
Some(MemoryLockSettings::Normal)
}
#[inline(always)]
fn advice_default() -> HashSet<MemoryAdvice>
{
use self::MemoryAdvice::*;
fast_secure_hash_set!
{
DontFork
}
}
}