mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 13:32:45 +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
					
				
					 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling