瀏覽代碼

Kernel: Fix regression where MemoryManager is initialized twice

MemoryManager cannot use the Singleton class because
MemoryManager::initialize is called before the global constructors
are run. That caused the Singleton to be re-initialized, causing
it to create another MemoryManager instance.
Tom 5 年之前
父節點
當前提交
8a75e0b892
共有 2 個文件被更改,包括 7 次插入6 次删除
  1. 6 5
      Kernel/VM/MemoryManager.cpp
  2. 1 1
      Kernel/VM/MemoryManager.h

+ 6 - 5
Kernel/VM/MemoryManager.cpp

@@ -26,7 +26,6 @@
 
 
 #include <AK/Assertions.h>
 #include <AK/Assertions.h>
 #include <AK/Memory.h>
 #include <AK/Memory.h>
-#include <AK/Singleton.h>
 #include <AK/StringView.h>
 #include <AK/StringView.h>
 #include <Kernel/Arch/i386/CPU.h>
 #include <Kernel/Arch/i386/CPU.h>
 #include <Kernel/CMOS.h>
 #include <Kernel/CMOS.h>
@@ -51,7 +50,11 @@ extern FlatPtr end_of_kernel_bss;
 
 
 namespace Kernel {
 namespace Kernel {
 
 
-static auto s_the = AK::make_singleton<MemoryManager>();
+// NOTE: We can NOT use AK::Singleton for this class, because
+// MemoryManager::initialize is called *before* global constructors are
+// run. If we do, then AK::Singleton would get re-initialized, causing
+// the memory manager to be initialized twice!
+static MemoryManager* s_the;
 RecursiveSpinLock s_mm_lock;
 RecursiveSpinLock s_mm_lock;
 
 
 MemoryManager& MM
 MemoryManager& MM
@@ -61,8 +64,6 @@ MemoryManager& MM
 
 
 MemoryManager::MemoryManager()
 MemoryManager::MemoryManager()
 {
 {
-    ASSERT(!s_the.is_initialized());
-
     ScopedSpinLock lock(s_mm_lock);
     ScopedSpinLock lock(s_mm_lock);
     m_kernel_page_directory = PageDirectory::create_kernel_page_directory();
     m_kernel_page_directory = PageDirectory::create_kernel_page_directory();
     parse_memory_map();
     parse_memory_map();
@@ -220,7 +221,7 @@ void MemoryManager::initialize(u32 cpu)
     Processor::current().set_mm_data(*mm_data);
     Processor::current().set_mm_data(*mm_data);
 
 
     if (cpu == 0)
     if (cpu == 0)
-        s_the.ensure_instance();
+        s_the = new MemoryManager;
 }
 }
 
 
 Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress vaddr)
 Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress vaddr)

+ 1 - 1
Kernel/VM/MemoryManager.h

@@ -85,7 +85,6 @@ class MemoryManager {
     friend Optional<KBuffer> procfs$memstat(InodeIdentifier);
     friend Optional<KBuffer> procfs$memstat(InodeIdentifier);
 
 
 public:
 public:
-    MemoryManager();
     static MemoryManager& the();
     static MemoryManager& the();
 
 
     static void initialize(u32 cpu);
     static void initialize(u32 cpu);
@@ -161,6 +160,7 @@ public:
     PageDirectory& kernel_page_directory() { return *m_kernel_page_directory; }
     PageDirectory& kernel_page_directory() { return *m_kernel_page_directory; }
 
 
 private:
 private:
+    MemoryManager();
     ~MemoryManager();
     ~MemoryManager();
 
 
     enum class AccessSpace { Kernel,
     enum class AccessSpace { Kernel,