process_group.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. use super::{
  2. session::{Session, Sid},
  3. Pid, ProcessControlBlock, ProcessManager,
  4. };
  5. use crate::libs::spinlock::SpinLock;
  6. use alloc::{
  7. collections::BTreeMap,
  8. sync::{Arc, Weak},
  9. };
  10. use hashbrown::HashMap;
  11. use system_error::SystemError;
  12. /// 进程组ID
  13. pub type Pgid = Pid;
  14. /// 系统中所有进程组
  15. pub static ALL_PROCESS_GROUP: SpinLock<Option<HashMap<Pgid, Arc<ProcessGroup>>>> =
  16. SpinLock::new(None);
  17. #[derive(Debug)]
  18. pub struct ProcessGroup {
  19. /// 进程组pgid
  20. pub pgid: Pgid,
  21. pub process_group_inner: SpinLock<PGInner>,
  22. }
  23. #[derive(Debug)]
  24. pub struct PGInner {
  25. pub processes: BTreeMap<Pid, Arc<ProcessControlBlock>>,
  26. pub leader: Option<Arc<ProcessControlBlock>>,
  27. pub session: Weak<Session>,
  28. }
  29. impl PGInner {
  30. pub fn remove_process(&mut self, pid: &Pid) {
  31. if let Some(process) = self.processes.remove(pid) {
  32. if let Some(leader) = &self.leader {
  33. if Arc::ptr_eq(leader, &process) {
  34. self.leader = None;
  35. }
  36. }
  37. }
  38. }
  39. pub fn is_empty(&self) -> bool {
  40. self.processes.is_empty()
  41. }
  42. }
  43. impl ProcessGroup {
  44. pub fn new(pcb: Arc<ProcessControlBlock>) -> Arc<Self> {
  45. let pid = pcb.pid();
  46. let mut processes = BTreeMap::new();
  47. processes.insert(pid, pcb.clone());
  48. let inner = PGInner {
  49. processes,
  50. leader: Some(pcb),
  51. session: Weak::new(),
  52. };
  53. // log::debug!("New ProcessGroup {:?}", pid);
  54. Arc::new(Self {
  55. pgid: pid,
  56. process_group_inner: SpinLock::new(inner),
  57. })
  58. }
  59. pub fn contains(&self, pid: Pid) -> bool {
  60. self.process_group_inner.lock().processes.contains_key(&pid)
  61. }
  62. pub fn pgid(&self) -> Pgid {
  63. self.pgid
  64. }
  65. pub fn leader(&self) -> Option<Arc<ProcessControlBlock>> {
  66. self.process_group_inner.lock().leader.clone()
  67. }
  68. pub fn session(&self) -> Option<Arc<Session>> {
  69. // log::debug!("Before lock");
  70. let guard = self.process_group_inner.lock();
  71. // log::debug!("Locking");
  72. let session = guard.session.upgrade();
  73. drop(guard);
  74. // log::debug!("After lock");
  75. return session;
  76. }
  77. pub fn broadcast(&self) {
  78. unimplemented!("broadcast not supported yet");
  79. }
  80. pub fn sid(&self) -> Sid {
  81. if let Some(session) = self.session() {
  82. return session.sid();
  83. }
  84. Sid::from(0)
  85. }
  86. }
  87. impl Drop for ProcessGroup {
  88. fn drop(&mut self) {
  89. let mut inner = self.process_group_inner.lock();
  90. if let Some(leader) = inner.leader.take() {
  91. // 组长进程仍然在进程列表中,不应该直接销毁
  92. if inner.processes.contains_key(&leader.pid()) {
  93. inner.leader = Some(leader);
  94. }
  95. }
  96. inner.processes.clear();
  97. if let Some(session) = inner.session.upgrade() {
  98. let mut session_inner = session.session_inner.lock();
  99. session_inner.process_groups.remove(&self.pgid);
  100. if session_inner.should_destory() {
  101. ProcessManager::remove_session(session.sid());
  102. }
  103. }
  104. // log::debug!("Dropping pg {:?}", self.pgid.clone());
  105. }
  106. }
  107. impl ProcessManager {
  108. /// 根据pgid获取进程组
  109. ///
  110. /// ## 参数
  111. ///
  112. /// - `pgid` : 进程组的pgid
  113. ///
  114. /// ## 返回值
  115. ///
  116. /// 如果找到了对应的进程组,那么返回该进程组,否则返回None
  117. pub fn find_process_group(pgid: Pgid) -> Option<Arc<ProcessGroup>> {
  118. return ALL_PROCESS_GROUP
  119. .lock_irqsave()
  120. .as_ref()?
  121. .get(&pgid)
  122. .cloned();
  123. }
  124. /// 向系统中添加一个进程组
  125. ///
  126. /// ## 参数
  127. ///
  128. /// - `pg` : Arc<ProcessGroup>
  129. ///
  130. /// ## 返回值
  131. ///
  132. /// 无
  133. pub fn add_process_group(pg: Arc<ProcessGroup>) {
  134. ALL_PROCESS_GROUP
  135. .lock_irqsave()
  136. .as_mut()
  137. .unwrap()
  138. .insert(pg.pgid(), pg.clone());
  139. // log::debug!("New ProcessGroup added, pgid: {:?}", pg.pgid());
  140. }
  141. /// 删除一个进程组
  142. pub fn remove_process_group(pgid: Pgid) {
  143. // log::debug!("Removing pg {:?}", pgid.clone());
  144. let mut all_groups = ALL_PROCESS_GROUP.lock_irqsave();
  145. if let Some(pg) = all_groups.as_mut().unwrap().remove(&pgid) {
  146. // log::debug!("count: {:?}", Arc::strong_count(&pg));
  147. if Arc::strong_count(&pg) <= 2 {
  148. // 这里 Arc 计数小于等于 2,意味着它只有在 all_groups 里有一个引用,移除后会自动释放
  149. drop(pg);
  150. }
  151. }
  152. }
  153. }
  154. impl ProcessControlBlock {
  155. #[inline(always)]
  156. pub fn pgid(&self) -> Pgid {
  157. if let Some(process_group) = self.process_group.lock().upgrade() {
  158. process_group.pgid()
  159. } else {
  160. Pgid::from(0)
  161. }
  162. }
  163. #[inline(always)]
  164. pub fn process_group(&self) -> Option<Arc<ProcessGroup>> {
  165. self.process_group.lock().upgrade()
  166. }
  167. pub fn set_process_group(&self, pg: &Arc<ProcessGroup>) {
  168. if let Some(pcb) = self.self_ref.upgrade() {
  169. *pcb.process_group.lock() = Arc::downgrade(pg);
  170. // log::debug!("pid: {:?} set pgid: {:?}", self.pid(), pg.pgid());
  171. }
  172. }
  173. pub fn is_process_group_leader(&self) -> bool {
  174. if let Some(pcb) = self.self_ref.upgrade() {
  175. let pg = self.process_group().unwrap();
  176. if let Some(leader) = pg.leader() {
  177. return Arc::ptr_eq(&pcb, &leader);
  178. }
  179. }
  180. return false;
  181. }
  182. /// 将进程加入到指定pgid的进程组中(无论该进程组是否已经存在)
  183. ///
  184. /// 如果进程组已经存在,则将进程加入到该进程组中
  185. /// 如果进程组不存在,则创建一个新的进程组,并将进程加入到该进程组中
  186. ///
  187. /// ## 参数
  188. /// `pgid` : 目标进程组的pgid
  189. ///
  190. /// ## 返回值
  191. /// 无
  192. pub fn join_other_group(&self, pgid: Pgid) -> Result<(), SystemError> {
  193. // if let Some(pcb) = self.self_ref.upgrade() {
  194. if self.pgid() == pgid {
  195. return Ok(());
  196. }
  197. if self.is_session_leader() {
  198. // 会话领导者不能加入其他进程组
  199. return Err(SystemError::EPERM);
  200. }
  201. if let Some(pg) = ProcessManager::find_process_group(pgid) {
  202. let session = self.session().unwrap();
  203. if !session.contains_process_group(&pg) {
  204. // 进程组和进程应该属于同一个会话
  205. return Err(SystemError::EPERM);
  206. }
  207. self.join_specified_group(&pg)?;
  208. } else {
  209. if pgid != self.pid() {
  210. // 进程组不存在,只能加入自己的进程组
  211. return Err(SystemError::EPERM);
  212. }
  213. self.join_new_group()?;
  214. }
  215. // }
  216. Ok(())
  217. }
  218. /// 将进程加入到新创建的进程组中
  219. fn join_new_group(&self) -> Result<(), SystemError> {
  220. let session = self.session().unwrap();
  221. let mut self_pg_mut = self.process_group.lock();
  222. if let Some(old_pg) = self_pg_mut.upgrade() {
  223. let mut old_pg_inner = old_pg.process_group_inner.lock();
  224. let mut session_inner = session.session_inner.lock();
  225. old_pg_inner.remove_process(&self.pid);
  226. *self_pg_mut = Weak::new();
  227. if old_pg_inner.is_empty() {
  228. ProcessManager::remove_process_group(old_pg.pgid());
  229. assert!(session_inner.process_groups.contains_key(&old_pg.pgid()));
  230. session_inner.process_groups.remove(&old_pg.pgid());
  231. }
  232. }
  233. let pcb = self.self_ref.upgrade().unwrap();
  234. let new_pg = ProcessGroup::new(pcb);
  235. let mut new_pg_inner = new_pg.process_group_inner.lock();
  236. let mut session_inner = session.session_inner.lock();
  237. *self_pg_mut = Arc::downgrade(&new_pg);
  238. ProcessManager::add_process_group(new_pg.clone());
  239. new_pg_inner.session = Arc::downgrade(&session);
  240. session_inner
  241. .process_groups
  242. .insert(new_pg.pgid, new_pg.clone());
  243. Ok(())
  244. }
  245. /// 将进程加入到指定的进程组中
  246. fn join_specified_group(&self, group: &Arc<ProcessGroup>) -> Result<(), SystemError> {
  247. let mut self_group = self.process_group.lock();
  248. let mut group_inner = if let Some(old_pg) = self_group.upgrade() {
  249. let (mut old_pg_inner, group_inner) = match old_pg.pgid().cmp(&group.pgid()) {
  250. core::cmp::Ordering::Equal => return Ok(()),
  251. core::cmp::Ordering::Less => (
  252. old_pg.process_group_inner.lock(),
  253. group.process_group_inner.lock(),
  254. ),
  255. core::cmp::Ordering::Greater => {
  256. let group_inner = group.process_group_inner.lock();
  257. let old_pg_inner = old_pg.process_group_inner.lock();
  258. (old_pg_inner, group_inner)
  259. }
  260. };
  261. old_pg_inner.remove_process(&self.pid);
  262. *self_group = Weak::new();
  263. if old_pg_inner.is_empty() {
  264. ProcessManager::remove_process_group(old_pg.pgid());
  265. }
  266. group_inner
  267. } else {
  268. group.process_group_inner.lock()
  269. };
  270. let pcb = self.self_ref.upgrade().unwrap();
  271. group_inner.processes.insert(self.pid, pcb);
  272. *self_group = Arc::downgrade(group);
  273. Ok(())
  274. }
  275. /// ### 清除自身的进程组以及会话引用(如果有的话),这个方法只能在进程退出时调用
  276. pub fn clear_pg_and_session_reference(&self) {
  277. if let Some(pg) = self.process_group() {
  278. let mut pg_inner = pg.process_group_inner.lock();
  279. pg_inner.remove_process(&self.pid());
  280. if pg_inner.is_empty() {
  281. // 如果进程组没有任何进程了,就删除该进程组
  282. ProcessManager::remove_process_group(pg.pgid());
  283. // log::debug!("clear_pg_reference: {:?}", pg.pgid());
  284. if let Some(session) = pg_inner.session.upgrade() {
  285. let mut session_inner = session.session_inner.lock();
  286. session_inner.remove_process_group(&pg.pgid());
  287. if session_inner.is_empty() {
  288. // 如果会话没有任何进程组了,就删除该会话
  289. ProcessManager::remove_session(session.sid());
  290. // log::debug!("clear_pg_reference: {:?}", session.sid());
  291. }
  292. }
  293. }
  294. }
  295. if let Some(session) = self.session() {
  296. let mut session_inner = session.session_inner.lock();
  297. if let Some(leader) = &session_inner.leader {
  298. if Arc::ptr_eq(leader, &self.self_ref.upgrade().unwrap()) {
  299. session_inner.leader = None;
  300. }
  301. }
  302. }
  303. }
  304. }