Ver Fonte

change(mm_list): rewrite `protect` with new syntax

greatbridf há 7 meses atrás
pai
commit
9f15decb66
2 ficheiros alterados com 31 adições e 58 exclusões
  1. 3 2
      src/kernel/mem/mm_area.rs
  2. 28 56
      src/kernel/mem/mm_list.rs

+ 3 - 2
src/kernel/mem/mm_area.rs

@@ -73,8 +73,9 @@ impl MMArea {
                     },
                 };
 
-                (*self.range.get_mut()) =
-                    self.range_borrow().shrink(self.range_borrow().end() - at);
+                let new_range = self.range_borrow().shrink(self.range_borrow().end() - at);
+
+                *self.range.get_mut() = new_range;
                 (Some(self), Some(right))
             }
         }

+ 28 - 56
src/kernel/mem/mm_list.rs

@@ -181,15 +181,34 @@ impl MMListInner<'_> {
             return Err(EINVAL);
         }
 
-        let mut left_area = None;
-        let mut right_area = None;
-        let mut mid_area = Vec::new();
-
-        self.areas.retain(|area| {
+        let mut found = false;
+        let old_areas = core::mem::take(&mut self.areas);
+        for mut area in old_areas {
             let Some((left, mid, right)) = area.range().mask_with_checked(&range_to_protect) else {
-                return true;
+                self.areas.insert(area);
+                continue;
             };
 
+            found = true;
+
+            if let Some(left) = left {
+                let (Some(left), Some(right)) = area.split(left.end()) else {
+                    unreachable!("`left.end()` is within the area");
+                };
+
+                self.areas.insert(left);
+                area = right;
+            }
+
+            if let Some(right) = right {
+                let (Some(left), Some(right)) = area.split(right.start()) else {
+                    unreachable!("`right.start()` is within the area");
+                };
+
+                self.areas.insert(right);
+                area = left;
+            }
+
             for pte in self.page_table.iter_user(mid) {
                 let mut page_attr = pte.get_attr().as_page_attr().expect("Not a page attribute");
 
@@ -204,59 +223,12 @@ impl MMListInner<'_> {
                 pte.set_attr(page_attr.into());
             }
 
-            match (left, right) {
-                (None, None) => {
-                    mid_area.push(area.clone());
-                }
-                (Some(left), None) => {
-                    assert!(left_area.is_none());
-                    let (Some(left), Some(right)) = area.clone().split(left.end()) else {
-                        unreachable!("`left.end()` is within the area");
-                    };
-
-                    left_area = Some(left);
-                    mid_area.push(right);
-                }
-                (None, Some(right)) => {
-                    assert!(right_area.is_none());
-                    let (Some(left), Some(right)) = area.clone().split(right.start()) else {
-                        unreachable!("`right.start()` is within the area");
-                    };
-
-                    mid_area.push(left);
-                    right_area = Some(right);
-                }
-                (Some(left), Some(right)) => {
-                    assert!(left_area.is_none());
-                    assert!(right_area.is_none());
-                    let (Some(left), Some(mid)) = area.clone().split(left.end()) else {
-                        unreachable!("`left.end()` is within the area");
-                    };
-
-                    let (Some(mid), Some(right)) = mid.split(right.start()) else {
-                        unreachable!("`right.start()` is within the area");
-                    };
-
-                    left_area = Some(left);
-                    right_area = Some(right);
-                    mid_area.push(mid);
-                }
-            }
-
-            false
-        });
-
-        assert!(mid_area.len() >= 1);
-
-        for mut area in mid_area {
             area.permission = permission;
             self.areas.insert(area);
         }
-        if let Some(front) = left_area {
-            self.areas.insert(front);
-        }
-        if let Some(back) = right_area {
-            self.areas.insert(back);
+
+        if !found {
+            return Err(ENOMEM);
         }
 
         Ok(())