Forráskód Böngészése

Add a kmalloc_eternal() for things that will never be destroyed.

Andreas Kling 6 éve
szülő
commit
9a086b2d35

+ 21 - 10
AK/Vector.h

@@ -6,16 +6,26 @@
 
 namespace AK {
 
-template<typename T> class Vector;
+template<typename T, typename Allocator> class Vector;
 
-template<typename T>
+struct KmallocAllocator {
+    static void* allocate(size_t size) { return kmalloc(size); }
+    static void deallocate(void* ptr) { kfree(ptr); }
+};
+
+struct KmallocEternalAllocator {
+    static void* allocate(size_t size) { return kmalloc_eternal(size); }
+    static void deallocate(void*) { }
+};
+
+template<typename T, typename Allocator>
 class VectorImpl {
 public:
     ~VectorImpl() { }
     static VectorImpl* create(size_t capacity)
     {
         size_t size = sizeof(VectorImpl) + sizeof(T) * capacity;
-        void* slot = kmalloc(size);
+        void* slot = Allocator::allocate(size);
         new (slot) VectorImpl(capacity);
         return (VectorImpl*)slot;
     }
@@ -39,7 +49,7 @@ public:
     }
 
 private:
-    friend class Vector<T>;
+    friend class Vector<T, Allocator>;
 
     VectorImpl(size_t capacity) : m_capacity(capacity) { }
 
@@ -53,7 +63,7 @@ private:
     size_t m_capacity;
 };
 
-template<typename T>
+template<typename T, typename Allocator = KmallocAllocator>
 class Vector {
 public:
     Vector() { }
@@ -79,7 +89,7 @@ public:
         for (size_t i = 0; i < size(); ++i) {
             at(i).~T();
         }
-        kfree(m_impl);
+        Allocator::deallocate(m_impl);
         m_impl = nullptr;
     }
 
@@ -150,14 +160,14 @@ public:
         if (capacity() >= neededCapacity)
             return;
         size_t newCapacity = paddedCapacity(neededCapacity);
-        auto newImpl = VectorImpl<T>::create(newCapacity);
+        auto newImpl = VectorImpl<T, Allocator>::create(newCapacity);
         if (m_impl) {
             newImpl->m_size = m_impl->m_size;
             for (size_t i = 0; i < size(); ++i) {
                 new (newImpl->slot(i)) T(move(m_impl->at(i)));
                 m_impl->at(i).~T();
             }
-            kfree(m_impl);
+            Allocator::deallocate(m_impl);
         }
         m_impl = newImpl;
     }
@@ -198,10 +208,11 @@ private:
         return max(size_t(4), capacity + (capacity / 4) + 4);
     }
 
-    VectorImpl<T>* m_impl { nullptr };
+    VectorImpl<T, Allocator>* m_impl { nullptr };
 };
 
 }
 
 using AK::Vector;
-
+using AK::KmallocEternalAllocator;
+using AK::KmallocAllocator;

+ 12 - 0
AK/kmalloc.cpp

@@ -39,6 +39,11 @@ void* krealloc(void* ptr, size_t size)
     return realloc(ptr, size);
 }
 
+void* kmalloc_eternal(size_t size)
+{
+    return kmalloc(size);
+}
+
 }
 
 #else
@@ -59,6 +64,13 @@ void* kmalloc(size_t size)
     return SimpleMalloc::allocate(size);
 }
 
+void* kmalloc_eternal(size_t size)
+{
+    if (!size)
+        return nullptr;
+    return SimpleMalloc::allocate(size);
+}
+
 void kfree(void* ptr)
 {
     if (!ptr)

+ 11 - 0
AK/kmalloc.h

@@ -2,6 +2,15 @@
 
 #include "Compiler.h"
 
+#if defined(SERENITY) && defined(KERNEL)
+#define AK_MAKE_ETERNAL \
+public: \
+    void* operator new(size_t size) { return kmalloc_eternal(size); } \
+private:
+#else
+#define AK_MAKE_ETERNAL
+#endif
+
 #ifdef SERENITY
 #ifdef KERNEL
 #include <Kernel/kmalloc.h>
@@ -14,6 +23,7 @@ void* kcalloc(size_t nmemb, size_t size);
 void* kmalloc(size_t size) MALLOC_ATTR;
 void kfree(void* ptr);
 void* krealloc(void* ptr, size_t size);
+void* kmalloc_eternal(size_t) MALLOC_ATTR;
 
 }
 
@@ -61,6 +71,7 @@ void* kcalloc(size_t nmemb, size_t size);
 void* kmalloc(size_t size) MALLOC_ATTR;
 void kfree(void* ptr);
 void* krealloc(void* ptr, size_t size);
+void* kmalloc_eternal(size_t) MALLOC_ATTR;
 
 }
 

+ 1 - 0
Kernel/Console.h

@@ -11,6 +11,7 @@ public:
 };
 
 class Console final : public CharacterDevice {
+    AK_MAKE_ETERNAL
 public:
     static Console& the() PURE;
 

+ 1 - 0
Kernel/Keyboard.h

@@ -13,6 +13,7 @@ public:
 };
 
 class Keyboard final : public IRQHandler, public CharacterDevice {
+    AK_MAKE_ETERNAL
 public:
     static Keyboard& the() PURE;
 

+ 1 - 0
Kernel/MemoryManager.h

@@ -36,6 +36,7 @@ bool copyToZone(Zone&, const void* data, size_t);
 #define MM MemoryManager::the()
 
 class MemoryManager {
+    AK_MAKE_ETERNAL
     friend ByteBuffer procfs$mm();
 public:
     static MemoryManager& the() PURE;

+ 1 - 1
Kernel/ProcFileSystem.cpp

@@ -174,7 +174,7 @@ ByteBuffer procfs$kmalloc()
     InterruptDisabler disabler;
     auto buffer = ByteBuffer::createUninitialized(128);
     char* ptr = (char*)buffer.pointer();
-    ptr += ksprintf(ptr, "alloc: %u\nfree:  %u\n", sum_alloc, sum_free);
+    ptr += ksprintf(ptr, "eternal:   %u\nallocated: %u\nfree:      %u\n", kmalloc_sum_eternal, sum_alloc, sum_free);
     buffer.trim(ptr - (char*)buffer.pointer());
     return buffer;
 }

+ 1 - 1
Kernel/Task.cpp

@@ -454,7 +454,7 @@ Task::Task(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel ring,
     if (isRing0()) {
         // FIXME: This memory is leaked.
         // But uh, there's also no kernel task termination, so I guess it's not technically leaked...
-        dword stackBottom = (dword)kmalloc(defaultStackSize);
+        dword stackBottom = (dword)kmalloc_eternal(defaultStackSize);
         m_stackTop0 = (stackBottom + defaultStackSize) & 0xffffff8;
         m_tss.esp = m_stackTop0;
     } else {

+ 1 - 1
Kernel/VirtualConsole.cpp

@@ -22,7 +22,7 @@ VirtualConsole::VirtualConsole(unsigned index, InitialContents initialContents)
     , m_index(index)
 {
     s_consoles[index] = this;
-    m_buffer = (byte*)kmalloc(80 * 25 * 2);
+    m_buffer = (byte*)kmalloc_eternal(80 * 25 * 2);
     dbgprintf("VirtualConsole %u @ %p, m_buffer = %p\n", index, this, m_buffer);
     if (initialContents == AdoptCurrentVGABuffer) {
         memcpy(m_buffer, s_vgaBuffer, 80 * 25 * 2);

+ 1 - 0
Kernel/VirtualConsole.h

@@ -5,6 +5,7 @@
 #include "Console.h"
 
 class VirtualConsole final : public TTY, public KeyboardClient, public ConsoleImplementation {
+    AK_MAKE_ETERNAL
 public:
     enum InitialContents { Cleared, AdoptCurrentVGABuffer };
 

+ 3 - 3
Kernel/i386.cpp

@@ -310,7 +310,7 @@ void flushGDT()
 
 void gdt_init()
 {
-    s_gdt = new Descriptor[256];
+    s_gdt = static_cast<Descriptor*>(kmalloc_eternal(sizeof(Descriptor) * 256));
     s_gdtLength = 5;
 
     s_gdtr.address = s_gdt;
@@ -378,7 +378,7 @@ asm(
 
 void idt_init()
 {
-    s_idt = new Descriptor[256];
+    s_idt = static_cast<Descriptor*>(kmalloc_eternal(sizeof(Descriptor) * 256));
 
     s_idtr.address = s_idt;
     s_idtr.size = 0x100 * 8;
@@ -406,7 +406,7 @@ void idt_init()
 
     registerInterruptHandler(0x57, irq7_handler);
 
-    s_irqHandler = new IRQHandler*[16];
+    s_irqHandler = static_cast<IRQHandler**>(kmalloc_eternal(sizeof(IRQHandler*) * 16));
     for (byte i = 0; i < 16; ++i) {
         s_irqHandler[i] = nullptr;
     }

+ 6 - 3
Kernel/init.cpp

@@ -48,9 +48,9 @@ static byte parseHexDigit(char nibble)
     return 10 + (nibble - 'a');
 }
 
-static Vector<KSym>* s_ksyms;
+static Vector<KSym, KmallocEternalAllocator>* s_ksyms;
 
-Vector<KSym>& ksyms()
+Vector<KSym, KmallocEternalAllocator>& ksyms()
 {
     return *s_ksyms;
 }
@@ -68,7 +68,9 @@ const KSym* ksymbolicate(dword address)
 
 static void loadKsyms(const ByteBuffer& buffer)
 {
-    s_ksyms = new Vector<KSym>;
+    // FIXME: It's gross that this vector grows dynamically rather than being sized-to-fit.
+    //        We're wasting that eternal kmalloc memory.
+    s_ksyms = new Vector<KSym, KmallocEternalAllocator>;
     auto* bufptr = (const char*)buffer.pointer();
     auto* startOfName = bufptr;
     dword address = 0;
@@ -83,6 +85,7 @@ static void loadKsyms(const ByteBuffer& buffer)
                 break;
             }
         }
+        // FIXME: The Strings here should be eternally allocated too.
         ksyms().append({ address, String(startOfName, bufptr - startOfName) });
         ++bufptr;
     }

+ 17 - 0
Kernel/kmalloc.cpp

@@ -22,15 +22,21 @@ typedef struct
 #define CHUNK_SIZE  128
 #define POOL_SIZE   (1024 * 1024)
 
+#define ETERNAL_BASE_PHYSICAL 0x300000
 #define BASE_PHYS   0x200000
 
 PRIVATE BYTE alloc_map[POOL_SIZE / CHUNK_SIZE / 8];
 
 volatile DWORD sum_alloc = 0;
 volatile DWORD sum_free = POOL_SIZE;
+volatile size_t kmalloc_sum_eternal = 0;
+
+static byte* s_next_eternal_ptr;
 
 bool is_kmalloc_address(void* ptr)
 {
+    if (ptr >= (byte*)ETERNAL_BASE_PHYSICAL && ptr < s_next_eternal_ptr)
+        return true;
     return ptr >= (void*)BASE_PHYS && ptr <= ((void*)BASE_PHYS + POOL_SIZE);
 }
 
@@ -40,8 +46,19 @@ kmalloc_init()
     memset( &alloc_map, 0, sizeof(alloc_map) );
     memset( (void *)BASE_PHYS, 0, POOL_SIZE );
 
+    kmalloc_sum_eternal = 0;
     sum_alloc = 0;
     sum_free = POOL_SIZE;
+
+    s_next_eternal_ptr = (byte*)ETERNAL_BASE_PHYSICAL;
+}
+
+void* kmalloc_eternal(size_t size)
+{
+    void* ptr = s_next_eternal_ptr;
+    s_next_eternal_ptr += size;
+    kmalloc_sum_eternal += size;
+    return ptr;
 }
 
 PUBLIC void *

+ 2 - 0
Kernel/kmalloc.h

@@ -2,12 +2,14 @@
 
 void kmalloc_init();
 void *kmalloc(DWORD size) __attribute__ ((malloc));
+void* kmalloc_eternal(size_t) __attribute__ ((malloc));
 void kfree(void*);
 
 bool is_kmalloc_address(void*);
 
 extern volatile DWORD sum_alloc;
 extern volatile DWORD sum_free;
+extern volatile dword kmalloc_sum_eternal;
 
 inline void* operator new(size_t, void* p) { return p; }
 inline void* operator new[](size_t, void* p) { return p; }

+ 1 - 1
Kernel/system.h

@@ -9,7 +9,7 @@ struct KSym {
     String name;
 };
 
-Vector<KSym>& ksyms() PURE;
+Vector<KSym, KmallocEternalAllocator>& ksyms() PURE;
 const KSym* ksymbolicate(dword address) PURE;
 
 struct system_t

+ 1 - 0
VirtualFileSystem/FullDevice.h

@@ -3,6 +3,7 @@
 #include "CharacterDevice.h"
 
 class FullDevice final : public CharacterDevice {
+    AK_MAKE_ETERNAL
 public:
     FullDevice();
     virtual ~FullDevice();

+ 1 - 0
VirtualFileSystem/NullDevice.h

@@ -3,6 +3,7 @@
 #include "CharacterDevice.h"
 
 class NullDevice final : public CharacterDevice {
+    AK_MAKE_ETERNAL
 public:
     NullDevice();
     virtual ~NullDevice() override;

+ 1 - 0
VirtualFileSystem/RandomDevice.h

@@ -3,6 +3,7 @@
 #include "CharacterDevice.h"
 
 class RandomDevice final : public CharacterDevice {
+    AK_MAKE_ETERNAL
 public:
     RandomDevice();
     virtual ~RandomDevice() override;

+ 1 - 0
VirtualFileSystem/VirtualFileSystem.h

@@ -28,6 +28,7 @@ inline constexpr dword encodedDevice(unsigned major, unsigned minor)
 }
 
 class VirtualFileSystem {
+    AK_MAKE_ETERNAL
 public:
     static void initializeGlobals();
     static SpinLock& lock();

+ 1 - 0
VirtualFileSystem/ZeroDevice.h

@@ -3,6 +3,7 @@
 #include "CharacterDevice.h"
 
 class ZeroDevice final : public CharacterDevice {
+    AK_MAKE_ETERNAL
 public:
     ZeroDevice();
     virtual ~ZeroDevice() override;