#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[derive(Deserialize, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct ProcessNiceConfiguration
{
pub share_of_cpu_cycles_in_autogroup: Option<Nice>,
pub all_other_processes_for_current_user: Option<Nice>,
pub all_other_processes_in_process_group: Option<Nice>,
pub current_process_priority: Option<Nice>,
}
impl Default for ProcessNiceConfiguration
{
#[inline(always)]
fn default() -> Self
{
Self
{
share_of_cpu_cycles_in_autogroup: Some(Nice::Negative_20),
all_other_processes_for_current_user: Some(Nice::Positive_19),
all_other_processes_in_process_group: Some(Nice::Positive_19),
current_process_priority: Some(Nice::Negative_20),
}
}
}
impl ProcessNiceConfiguration
{
#[inline(always)]
pub fn configure(&self, proc_path: &ProcPath) -> Result<(), ProcessNiceConfigurationError>
{
#[inline(always)]
fn set_nice_value<Error>(nice_value: Option<Nice>, function: impl FnOnce(Nice) -> Result<(), Error>, error: impl FnOnce(Error) -> ProcessNiceConfigurationError) -> Result<(), ProcessNiceConfigurationError>
{
if let Some(nice_value) = nice_value
{
function(nice_value).map_err(|cause| error(cause))
}
else
{
Ok(())
}
}
use self::ProcessNiceConfigurationError::*;
set_nice_value(self.share_of_cpu_cycles_in_autogroup, |nice| Self::set_autogroup_for_current_process_if_desired(nice, proc_path), CouldNotSetCurrentProcessAutogroupPriorityNice)?;
set_nice_value(self.all_other_processes_for_current_user, |nice| nice.set_real_user_priority(UserIdentifier::default()), |_: ()| CouldNotSetCurrentUserPriorityNice)?;
set_nice_value(self.all_other_processes_in_process_group, |nice| nice.set_process_group_priority(ProcessGroupIdentifierChoice::Current), |_: ()| CouldNotSetCurrentProcessGroupPriorityNice)?;
set_nice_value(self.current_process_priority, |nice| nice.set_process_priority(ProcessIdentifierChoice::Current), |_: ()| CouldNotSetCurrentProcessPriorityNice)?;
Ok(())
}
#[inline(always)]
fn set_autogroup_for_current_process_if_desired(share_of_cpu_cycles_in_autogroup: Nice, proc_path: &ProcPath) -> Result<(), io::Error>
{
if Self::is_autogroup_active(proc_path)?
{
share_of_cpu_cycles_in_autogroup.set_autogroup_for_current_process(proc_path)
}
else
{
Ok(())
}
}
#[inline(always)]
fn is_autogroup_active(proc_path: &ProcPath) -> Result<bool, io::Error>
{
Self::sched_autogroup_enabled_file_path(proc_path).read_zero_or_one_bool()
}
#[inline(always)]
fn sched_autogroup_enabled_file_path(proc_path: &ProcPath) -> PathBuf
{
proc_path.sys_kernel_file_path("sched_autogroup_enabled")
}
}