mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
Use a freelist for GDT entries.
Tweak the kmalloc space layout a bit. Get the spawn stress test up and running again.
This commit is contained in:
parent
9da4864a9a
commit
c70afd045e
Notes:
sideshowbarker
2024-07-19 18:34:40 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c70afd045e5
6 changed files with 40 additions and 21 deletions
|
@ -62,7 +62,7 @@ static bool contextSwitch(Process*);
|
|||
static void redoKernelProcessTSS()
|
||||
{
|
||||
if (!s_kernelProcess->selector())
|
||||
s_kernelProcess->setSelector(allocateGDTEntry());
|
||||
s_kernelProcess->setSelector(gdt_alloc_entry());
|
||||
|
||||
auto& tssDescriptor = getGDTEntry(s_kernelProcess->selector());
|
||||
|
||||
|
@ -109,14 +109,14 @@ void Process::allocateLDT()
|
|||
{
|
||||
ASSERT(!m_tss.ldt);
|
||||
static const WORD numLDTEntries = 4;
|
||||
WORD newLDTSelector = allocateGDTEntry();
|
||||
m_ldt_selector = gdt_alloc_entry();
|
||||
m_ldtEntries = new Descriptor[numLDTEntries];
|
||||
#if 0
|
||||
kprintf("new ldt selector = %x\n", newLDTSelector);
|
||||
kprintf("new ldt selector = %x\n", m_ldt_selector);
|
||||
kprintf("new ldt table at = %p\n", m_ldtEntries);
|
||||
kprintf("new ldt table size = %u\n", (numLDTEntries * 8) - 1);
|
||||
#endif
|
||||
Descriptor& ldt = getGDTEntry(newLDTSelector);
|
||||
Descriptor& ldt = getGDTEntry(m_ldt_selector);
|
||||
ldt.setBase(m_ldtEntries);
|
||||
ldt.setLimit(numLDTEntries * 8 - 1);
|
||||
ldt.dpl = 0;
|
||||
|
@ -126,7 +126,7 @@ void Process::allocateLDT()
|
|||
ldt.operation_size = 1;
|
||||
ldt.descriptor_type = 0;
|
||||
ldt.type = Descriptor::LDT;
|
||||
m_tss.ldt = newLDTSelector;
|
||||
m_tss.ldt = m_ldt_selector;
|
||||
}
|
||||
|
||||
Vector<Process*> Process::allProcesses()
|
||||
|
@ -489,8 +489,14 @@ Process::~Process()
|
|||
InterruptDisabler disabler;
|
||||
ProcFileSystem::the().removeProcess(*this);
|
||||
system.nprocess--;
|
||||
delete [] m_ldtEntries;
|
||||
m_ldtEntries = nullptr;
|
||||
|
||||
if (isRing3()) {
|
||||
delete [] m_ldtEntries;
|
||||
m_ldtEntries = nullptr;
|
||||
gdt_free_entry(m_ldt_selector);
|
||||
}
|
||||
|
||||
gdt_free_entry(selector());
|
||||
|
||||
if (m_kernelStack) {
|
||||
kfree(m_kernelStack);
|
||||
|
@ -754,7 +760,7 @@ static bool contextSwitch(Process* t)
|
|||
t->set_state(Process::Running);
|
||||
|
||||
if (!t->selector()) {
|
||||
t->setSelector(allocateGDTEntry());
|
||||
t->setSelector(gdt_alloc_entry());
|
||||
auto& descriptor = getGDTEntry(t->selector());
|
||||
descriptor.setBase(&t->tss());
|
||||
descriptor.setLimit(0xffff);
|
||||
|
|
|
@ -167,6 +167,7 @@ private:
|
|||
State m_state { Invalid };
|
||||
DWORD m_wakeupTime { 0 };
|
||||
TSS32 m_tss;
|
||||
word m_ldt_selector { 0 };
|
||||
Descriptor* m_ldtEntries { nullptr };
|
||||
Vector<OwnPtr<FileHandle>> m_file_descriptors;
|
||||
RingLevel m_ring { Ring0 };
|
||||
|
|
|
@ -20,15 +20,20 @@ static Descriptor* s_gdt;
|
|||
|
||||
static IRQHandler** s_irqHandler;
|
||||
|
||||
static Vector<word, KmallocEternalAllocator>* s_gdt_freelist;
|
||||
|
||||
static WORD s_gdtLength;
|
||||
|
||||
WORD allocateGDTEntry()
|
||||
word gdt_alloc_entry()
|
||||
{
|
||||
// FIXME: This should not grow indefinitely.
|
||||
ASSERT(s_gdtLength < 256);
|
||||
WORD newGDTEntry = s_gdtLength * 8;
|
||||
s_gdtLength++;
|
||||
return newGDTEntry;
|
||||
ASSERT(s_gdt_freelist);
|
||||
ASSERT(!s_gdt_freelist->isEmpty());
|
||||
return s_gdt_freelist->takeLast();
|
||||
}
|
||||
|
||||
void gdt_free_entry(word entry)
|
||||
{
|
||||
s_gdt_freelist->append(entry);
|
||||
}
|
||||
|
||||
extern "C" void handleIRQ();
|
||||
|
@ -310,6 +315,12 @@ void gdt_init()
|
|||
s_gdt = static_cast<Descriptor*>(kmalloc_eternal(sizeof(Descriptor) * 256));
|
||||
s_gdtLength = 5;
|
||||
|
||||
s_gdt_freelist = new Vector<word, KmallocEternalAllocator>();
|
||||
s_gdt_freelist->ensureCapacity(256);
|
||||
for (size_t i = s_gdtLength; i < 256; ++i)
|
||||
s_gdt_freelist->uncheckedAppend(i * 8);
|
||||
|
||||
s_gdtLength = 256;
|
||||
s_gdtr.address = s_gdt;
|
||||
s_gdtr.size = (s_gdtLength * 8) - 1;
|
||||
|
||||
|
|
|
@ -66,7 +66,8 @@ void unregisterIRQHandler(BYTE number, IRQHandler&);
|
|||
void flushIDT();
|
||||
void flushGDT();
|
||||
void loadTaskRegister(WORD selector);
|
||||
WORD allocateGDTEntry();
|
||||
word gdt_alloc_entry();
|
||||
void gdt_free_entry(word);
|
||||
Descriptor& getGDTEntry(WORD selector);
|
||||
void writeGDTEntry(WORD selector, Descriptor&);
|
||||
|
||||
|
|
|
@ -106,13 +106,13 @@ static void spawn_stress()
|
|||
{
|
||||
dword lastAlloc = sum_alloc;
|
||||
|
||||
for (unsigned i = 0; i < 100; ++i) {
|
||||
for (unsigned i = 0; i < 10000; ++i) {
|
||||
int error;
|
||||
Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0);
|
||||
kprintf("malloc stats: alloc:%u free:%u\n", sum_alloc, sum_free);
|
||||
kprintf("malloc stats: alloc:%u free:%u page_aligned:%u eternal:%u\n", sum_alloc, sum_free, kmalloc_page_aligned, kmalloc_sum_eternal);
|
||||
kprintf("delta:%u\n", sum_alloc - lastAlloc);
|
||||
lastAlloc = sum_alloc;
|
||||
sleep(600);
|
||||
sleep(60);
|
||||
}
|
||||
for (;;) {
|
||||
asm volatile("hlt");
|
||||
|
|
|
@ -22,9 +22,9 @@ typedef struct
|
|||
#define CHUNK_SIZE 128
|
||||
#define POOL_SIZE (1024 * 1024)
|
||||
|
||||
#define PAGE_ALIGNED_BASE_PHYSICAL 0x380000
|
||||
#define ETERNAL_BASE_PHYSICAL 0x300000
|
||||
#define BASE_PHYS 0x200000
|
||||
#define PAGE_ALIGNED_BASE_PHYSICAL 0x300000
|
||||
#define ETERNAL_BASE_PHYSICAL 0x200000
|
||||
#define BASE_PHYS 0x100000
|
||||
|
||||
PRIVATE BYTE alloc_map[POOL_SIZE / CHUNK_SIZE / 8];
|
||||
|
||||
|
|
Loading…
Reference in a new issue