Refine the implementation of NiceValue
				
					
				
			This commit is contained in:
		
							parent
							
								
									db3a31d42e
								
							
						
					
					
						commit
						f9839299b2
					
				| @ -36,8 +36,9 @@ impl ProcINode for ProcStatINode { | ||||
|         let stime = 0; | ||||
|         let cutime = 0; | ||||
|         let cstime = 0; | ||||
|         let priority = main_thread.nice().read().unwrap().to_priority_val(); | ||||
|         let nice = main_thread.nice().read().unwrap().raw_val(); | ||||
|         // Convert [19,-20] to [39,0].
 | ||||
|         let priority = main_thread.nice().read().unwrap().to_raw_val() + 20; | ||||
|         let nice = main_thread.nice().read().unwrap().to_raw_val(); | ||||
|         let num_threads = self.0.threads().len(); | ||||
|         let itrealvalue = 0; | ||||
|         let starttime = self.0.start_time(); | ||||
|  | ||||
| @ -42,6 +42,9 @@ pub struct Thread { | ||||
|     fs: FsViewRef, | ||||
|     files: FileTableRef, | ||||
|     sched: SchedAgentRef, | ||||
|     // According to POSIX, the nice value is a per-process setting.
 | ||||
|     // In our implementation, the threads belong to same process
 | ||||
|     // share the same nice value.
 | ||||
|     nice: NiceValueRef, | ||||
|     rlimits: ResourceLimitsRef, | ||||
|     // Signal
 | ||||
|  | ||||
| @ -2,18 +2,17 @@ use super::priority::{NiceValue, PrioWhich}; | ||||
| use crate::prelude::*; | ||||
| use crate::process::table::{get_all_processes, get_pgrp, get_process}; | ||||
| 
 | ||||
| pub fn do_set_priority(which: PrioWhich, who: i32, prio: NiceValue) -> Result<()> { | ||||
| pub fn do_set_priority(which: PrioWhich, who: i32, nice: NiceValue) -> Result<()> { | ||||
|     debug!( | ||||
|         "set_priority: which: {:?}, who: {}, prio: {:?}", | ||||
|         which, who, prio | ||||
|         "set_priority: which: {:?}, who: {}, nice: {:?}", | ||||
|         which, who, nice | ||||
|     ); | ||||
| 
 | ||||
|     let processes = get_processes(which, who)?; | ||||
|     for process in processes.iter() { | ||||
|         let main_thread = process | ||||
|             .main_thread() | ||||
|             .ok_or_else(|| errno!(ESRCH, "invalid pid"))?; | ||||
|         *main_thread.nice().write().unwrap() = prio; | ||||
|         for thread in process.threads().iter() { | ||||
|             *thread.nice().write().unwrap() = nice; | ||||
|         } | ||||
|     } | ||||
|     Ok(()) | ||||
| } | ||||
| @ -22,27 +21,25 @@ pub fn do_get_priority(which: PrioWhich, who: i32) -> Result<NiceValue> { | ||||
|     debug!("get_priority: which: {:?}, who: {}", which, who); | ||||
| 
 | ||||
|     let processes = get_processes(which, who)?; | ||||
|     let prio = { | ||||
|         let mut prio = NiceValue::max_value(); | ||||
|     let nice = { | ||||
|         let mut nice = NiceValue::MAX; | ||||
|         for process in processes.iter() { | ||||
|             let main_thread = process | ||||
|                 .main_thread() | ||||
|                 .ok_or_else(|| errno!(ESRCH, "invalid pid"))?; | ||||
|             let nice_value = main_thread.nice().read().unwrap(); | ||||
|             let current_nice = main_thread.nice().read().unwrap(); | ||||
|             // Returns the highest priority enjoyed by the processes
 | ||||
|             if *nice_value < prio { | ||||
|                 prio = *nice_value; | ||||
|             if *current_nice < nice { | ||||
|                 nice = *current_nice; | ||||
|             } | ||||
|         } | ||||
|         prio | ||||
|         nice | ||||
|     }; | ||||
|     Ok(prio) | ||||
|     Ok(nice) | ||||
| } | ||||
| 
 | ||||
| // According to POSIX, the nice value is a per-process setting.
 | ||||
| // In our implementation, the threads belong to same process share the same nice value.
 | ||||
| fn get_processes(which: PrioWhich, who: i32) -> Result<Vec<crate::process::ProcessRef>> { | ||||
|     Ok(match which { | ||||
|     let processes = match which { | ||||
|         PrioWhich::PRIO_PROCESS => { | ||||
|             let process = if who == 0 { | ||||
|                 current!().process().clone() | ||||
| @ -67,5 +64,10 @@ fn get_processes(which: PrioWhich, who: i32) -> Result<Vec<crate::process::Proce | ||||
|                 return_errno!(ESRCH, "no such user"); | ||||
|             } | ||||
|         } | ||||
|     }) | ||||
|     }; | ||||
|     if processes.is_empty() { | ||||
|         return_errno!(ESRCH, "no such process"); | ||||
|     } | ||||
| 
 | ||||
|     Ok(processes) | ||||
| } | ||||
|  | ||||
| @ -21,55 +21,48 @@ impl TryFrom<i32> for PrioWhich { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Process priority value
 | ||||
| /// Process scheduling nice value.
 | ||||
| ///
 | ||||
| /// Lower values give a process a higher scheduling priority.
 | ||||
| #[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)] | ||||
| pub struct NiceValue { | ||||
|     value: i32, | ||||
|     value: i8, | ||||
| } | ||||
| 
 | ||||
| impl NiceValue { | ||||
|     const MAX_PRIO: i32 = 19; | ||||
|     pub const MAX: Self = Self { value: 19 }; | ||||
| 
 | ||||
|     const MIN_PRIO: i32 = -20; | ||||
|     pub const MIN: Self = Self { value: -20 }; | ||||
| 
 | ||||
|     pub fn max_value() -> Self { | ||||
|         Self { | ||||
|             value: Self::MAX_PRIO, | ||||
|     /// Create a nice value from a raw value.
 | ||||
|     ///
 | ||||
|     /// The raw value given beyond the range are automatically adjusted
 | ||||
|     /// to the nearest boundary value.
 | ||||
|     pub fn new(raw: i8) -> Self { | ||||
|         if raw < Self::MIN.value { | ||||
|             Self::MIN | ||||
|         } else if raw > Self::MAX.value { | ||||
|             Self::MAX | ||||
|         } else { | ||||
|             Self { value: raw } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn min_value() -> Self { | ||||
|         Self { | ||||
|             value: Self::MIN_PRIO, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn raw_val(&self) -> i32 { | ||||
|     /// Convert to the raw value with range [19, -20].
 | ||||
|     pub fn to_raw_val(self) -> i8 { | ||||
|         self.value | ||||
|     } | ||||
| 
 | ||||
|     /// Convert [19,-20] to priority value [39,0].
 | ||||
|     pub fn to_priority_val(&self) -> i32 { | ||||
|         self.value - Self::MIN_PRIO | ||||
|     } | ||||
| 
 | ||||
|     /// Convert [19,-20] to rlimit style value [1,40].
 | ||||
|     pub fn to_rlimit_val(&self) -> i32 { | ||||
|         Self::MAX_PRIO - self.value + 1 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<i32> for NiceValue { | ||||
|     fn from(raw: i32) -> Self { | ||||
|         let value = if raw < Self::MIN_PRIO { | ||||
|             Self::MIN_PRIO | ||||
|         } else if raw > Self::MAX_PRIO { | ||||
|             Self::MAX_PRIO | ||||
|         let adj_raw = if raw > i8::MAX as i32 { | ||||
|             i8::MAX | ||||
|         } else if raw < i8::MIN as i32 { | ||||
|             i8::MIN | ||||
|         } else { | ||||
|             raw | ||||
|             raw as i8 | ||||
|         }; | ||||
|         Self { value } | ||||
|         Self::new(adj_raw) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -83,16 +83,16 @@ pub fn do_getcpu(cpu_ptr: *mut u32, node_ptr: *mut u32) -> Result<isize> { | ||||
| 
 | ||||
| pub fn do_set_priority(which: i32, who: i32, prio: i32) -> Result<isize> { | ||||
|     let which = PrioWhich::try_from(which)?; | ||||
|     let prio = NiceValue::from(prio); | ||||
|     super::do_priority::do_set_priority(which, who, prio)?; | ||||
|     let nice = NiceValue::from(prio); | ||||
|     super::do_priority::do_set_priority(which, who, nice)?; | ||||
|     Ok(0) | ||||
| } | ||||
| 
 | ||||
| pub fn do_get_priority(which: i32, who: i32) -> Result<isize> { | ||||
|     let which = PrioWhich::try_from(which)?; | ||||
|     let prio = super::do_priority::do_get_priority(which, who)?; | ||||
|     let nice = super::do_priority::do_get_priority(which, who)?; | ||||
|     // To avoid negative return values, "getpriority()" will
 | ||||
|     // not return the normal nice-value, but a negated value that
 | ||||
|     // has been offset by 20 (ie it returns 40..1 instead of -20..19)
 | ||||
|     Ok(prio.to_rlimit_val() as isize) | ||||
|     Ok((20 - nice.to_raw_val()) as _) | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user