summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-10-31 23:19:15 +0100
committerAndreas Kling <awesomekling@gmail.com>2018-10-31 23:19:15 +0100
commit9a086b2d3584f13d47e8d625035fe72cc2f3aea2 (patch)
treec6c30b245c909ddc7b80d8076fcc3e2edc847720
parentd980ddc74581a6894bf71b9eeb00461e9807e43f (diff)
downloadserenity-9a086b2d3584f13d47e8d625035fe72cc2f3aea2.zip
Add a kmalloc_eternal() for things that will never be destroyed.
-rw-r--r--AK/Vector.h31
-rw-r--r--AK/kmalloc.cpp12
-rw-r--r--AK/kmalloc.h11
-rw-r--r--Kernel/Console.h1
-rw-r--r--Kernel/Keyboard.h1
-rw-r--r--Kernel/MemoryManager.h1
-rw-r--r--Kernel/ProcFileSystem.cpp2
-rw-r--r--Kernel/Task.cpp2
-rw-r--r--Kernel/VirtualConsole.cpp2
-rw-r--r--Kernel/VirtualConsole.h1
-rw-r--r--Kernel/i386.cpp6
-rw-r--r--Kernel/init.cpp9
-rw-r--r--Kernel/kmalloc.cpp17
-rw-r--r--Kernel/kmalloc.h2
-rw-r--r--Kernel/system.h2
-rw-r--r--VirtualFileSystem/FullDevice.h1
-rw-r--r--VirtualFileSystem/NullDevice.h1
-rw-r--r--VirtualFileSystem/RandomDevice.h1
-rw-r--r--VirtualFileSystem/VirtualFileSystem.h1
-rw-r--r--VirtualFileSystem/ZeroDevice.h1
20 files changed, 85 insertions, 20 deletions
diff --git a/AK/Vector.h b/AK/Vector.h
index 10b7ee5dcd..8eb757100a 100644
--- a/AK/Vector.h
+++ b/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;
diff --git a/AK/kmalloc.cpp b/AK/kmalloc.cpp
index 80b662304f..3a5200dc23 100644
--- a/AK/kmalloc.cpp
+++ b/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)
diff --git a/AK/kmalloc.h b/AK/kmalloc.h
index 02b66c2aab..f62b6ea677 100644
--- a/AK/kmalloc.h
+++ b/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;
}
diff --git a/Kernel/Console.h b/Kernel/Console.h
index c870b086d5..ff225bf42b 100644
--- a/Kernel/Console.h
+++ b/Kernel/Console.h
@@ -11,6 +11,7 @@ public:
};
class Console final : public CharacterDevice {
+ AK_MAKE_ETERNAL
public:
static Console& the() PURE;
diff --git a/Kernel/Keyboard.h b/Kernel/Keyboard.h
index 3b8e75c747..7f374b840a 100644
--- a/Kernel/Keyboard.h
+++ b/Kernel/Keyboard.h
@@ -13,6 +13,7 @@ public:
};
class Keyboard final : public IRQHandler, public CharacterDevice {
+ AK_MAKE_ETERNAL
public:
static Keyboard& the() PURE;
diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h
index 0e749cbb53..c8e6a9ca5f 100644
--- a/Kernel/MemoryManager.h
+++ b/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;
diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp
index 64b2e6dc35..d8ba73f983 100644
--- a/Kernel/ProcFileSystem.cpp
+++ b/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;
}
diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp
index 8d26e9c02c..818e137782 100644
--- a/Kernel/Task.cpp
+++ b/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 {
diff --git a/Kernel/VirtualConsole.cpp b/Kernel/VirtualConsole.cpp
index b6479493e6..433b438d48 100644
--- a/Kernel/VirtualConsole.cpp
+++ b/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);
diff --git a/Kernel/VirtualConsole.h b/Kernel/VirtualConsole.h
index 79b4f0b510..e89d503c27 100644
--- a/Kernel/VirtualConsole.h
+++ b/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 };
diff --git a/Kernel/i386.cpp b/Kernel/i386.cpp
index d2c968fa06..562fd9a67b 100644
--- a/Kernel/i386.cpp
+++ b/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;
}
diff --git a/Kernel/init.cpp b/Kernel/init.cpp
index ea510179bf..c9f4706d85 100644
--- a/Kernel/init.cpp
+++ b/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;
}
diff --git a/Kernel/kmalloc.cpp b/Kernel/kmalloc.cpp
index 6d6825a5e2..b65f4b5936 100644
--- a/Kernel/kmalloc.cpp
+++ b/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 *
diff --git a/Kernel/kmalloc.h b/Kernel/kmalloc.h
index e0b5ac4955..72c295f465 100644
--- a/Kernel/kmalloc.h
+++ b/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; }
diff --git a/Kernel/system.h b/Kernel/system.h
index 0839f28d45..16fbc1220f 100644
--- a/Kernel/system.h
+++ b/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
diff --git a/VirtualFileSystem/FullDevice.h b/VirtualFileSystem/FullDevice.h
index f52dc5b8cb..9ab209d2f9 100644
--- a/VirtualFileSystem/FullDevice.h
+++ b/VirtualFileSystem/FullDevice.h
@@ -3,6 +3,7 @@
#include "CharacterDevice.h"
class FullDevice final : public CharacterDevice {
+ AK_MAKE_ETERNAL
public:
FullDevice();
virtual ~FullDevice();
diff --git a/VirtualFileSystem/NullDevice.h b/VirtualFileSystem/NullDevice.h
index 74cffee686..3c22b1f781 100644
--- a/VirtualFileSystem/NullDevice.h
+++ b/VirtualFileSystem/NullDevice.h
@@ -3,6 +3,7 @@
#include "CharacterDevice.h"
class NullDevice final : public CharacterDevice {
+ AK_MAKE_ETERNAL
public:
NullDevice();
virtual ~NullDevice() override;
diff --git a/VirtualFileSystem/RandomDevice.h b/VirtualFileSystem/RandomDevice.h
index eaa91c223d..e91c324c19 100644
--- a/VirtualFileSystem/RandomDevice.h
+++ b/VirtualFileSystem/RandomDevice.h
@@ -3,6 +3,7 @@
#include "CharacterDevice.h"
class RandomDevice final : public CharacterDevice {
+ AK_MAKE_ETERNAL
public:
RandomDevice();
virtual ~RandomDevice() override;
diff --git a/VirtualFileSystem/VirtualFileSystem.h b/VirtualFileSystem/VirtualFileSystem.h
index 07a8d9a442..1ce34a3604 100644
--- a/VirtualFileSystem/VirtualFileSystem.h
+++ b/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();
diff --git a/VirtualFileSystem/ZeroDevice.h b/VirtualFileSystem/ZeroDevice.h
index f83cae7d47..ca0fa7828b 100644
--- a/VirtualFileSystem/ZeroDevice.h
+++ b/VirtualFileSystem/ZeroDevice.h
@@ -3,6 +3,7 @@
#include "CharacterDevice.h"
class ZeroDevice final : public CharacterDevice {
+ AK_MAKE_ETERNAL
public:
ZeroDevice();
virtual ~ZeroDevice() override;