Преглед на файлове

Merge branch 'master' into libc

greatbridf преди 2 години
родител
ревизия
521d554189
променени са 2 файла, в които са добавени 64 реда и са изтрити 26 реда
  1. 4 0
      include/kernel/mm.hpp
  2. 60 26
      include/types/map.hpp

+ 4 - 0
include/kernel/mm.hpp

@@ -183,6 +183,7 @@ public:
             }
 
             this->unmap(iter);
+            // TODO: handle memory leak
             iter = m_areas.erase(iter);
         }
     }
@@ -212,6 +213,7 @@ public:
 
     constexpr void unmap(iterator_type area)
     {
+        int i = 0;
         for (auto& pg : *area->pgs) {
             if (*pg.ref_count == 1) {
                 ki_free(pg.ref_count);
@@ -223,6 +225,8 @@ public:
             pg.phys_page_id = 0;
             pg.attr.v = 0;
             pg.pte->v = 0;
+
+            invalidate_tlb((uint32_t)area->start + (i++) * PAGE_SIZE);
         }
         area->attr.v = 0;
         area->start = 0;

+ 60 - 26
include/types/map.hpp

@@ -206,10 +206,6 @@ public:
 
         static constexpr void swap(node* first, node* second)
         {
-            node* p = first->parent;
-            node* cl = first->left;
-            node* cr = first->right;
-
             if (node::is_red(first)) {
                 first->color = second->color;
                 second->color = node_color::RED;
@@ -218,35 +214,67 @@ public:
                 second->color = node_color::BLACK;
             }
 
+            if (first->parent == second) {
+                node* tmp = first;
+                first = second;
+                second = tmp;
+            }
+
+            node* p = first->parent;
+            node* cl = first->left;
+            node* cr = first->right;
+
+            bool is_first_left = first->is_left_child();
+            bool is_second_left = second->is_left_child();
+
             if (!first->is_root()) {
-                if (first->is_left_child())
+                if (is_first_left)
                     p->left = second;
                 else
                     p->right = second;
             }
-            if (cl)
-                cl->parent = second;
-            if (cr)
-                cr->parent = second;
 
-            first->parent = second->parent;
             first->left = second->left;
             first->right = second->right;
+            if (first->left)
+                first->left->parent = first;
+            if (first->right)
+                first->right->parent = first;
+
+            if (second->parent == first) {
+                first->parent = second;
+                second->parent = p;
+
+                if (is_second_left) {
+                    if (cr)
+                        cr->parent = second;
+                    second->left = first;
+                    second->right = cr;
+                } else {
+                    if (cl)
+                        cl->parent = second;
+                    second->right = first;
+                    second->left = cl;
+                }
+            } else {
+                first->parent = second->parent;
+
+                if (cl)
+                    cl->parent = second;
+                if (cr)
+                    cr->parent = second;
+                second->left = cl;
+                second->right = cr;
+
+                if (!second->is_root()) {
+                    if (is_second_left)
+                        second->parent->left = first;
+                    else
+                        second->parent->right = first;
+                }
 
-            if (!second->is_root()) {
-                if (second->is_left_child())
-                    second->parent->left = first;
-                else
-                    second->parent->right = first;
+                second->parent = p;
             }
-            if (second->left)
-                second->left->parent = first;
-            if (second->right)
-                second->right->parent = first;
-
-            second->parent = p;
-            second->left = cl;
-            second->right = cr;
         }
     };
 
@@ -495,6 +523,9 @@ private:
     // @param: nd is guaranteed to be a leaf node
     constexpr void _erase(node* nd)
     {
+        if (nd->is_root())
+            return;
+
         if (node::is_black(nd)) {
             node* p = nd->parent;
             node* s = nullptr;
@@ -544,6 +575,7 @@ private:
                 }
             } else {
                 s->tored();
+                p->toblack();
                 this->_erase(p);
             }
         }
@@ -631,9 +663,11 @@ public:
         node* next = nd->next();
 
         while (!nd->is_leaf()) {
-            if (nd->is_root())
-                this->root = nd->right->leftmost();
-            node::swap(nd, nd->right->leftmost());
+            node* alt = nd->right ? nd->right->leftmost() : nd->left;
+            if (nd->is_root()) {
+                this->root = alt;
+            }
+            node::swap(nd, alt);
         }
 
         this->_erase(nd);