Implemented necessary changes for Process destruction. Processes clean up their memory when deleted.

This commit is contained in:
Xnoe 2021-12-01 17:05:46 +00:00
parent b7566ef777
commit a9ec673b24
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
11 changed files with 92 additions and 15 deletions

View File

@ -95,6 +95,30 @@ namespace xnoe {
current = current->next;
}
}
void remove(T elem) {
linkedlistelem<T>* current = start;
while (current) {
if (current->elem == elem) {
if (current->prev)
current->prev->next = current->next;
if (current->next)
current->next->prev = current->prev;
if (current == start)
start = current->next;
if (current == end)
end = current->prev;
delete current;
return;
}
current = current->next;
}
}
};
}

View File

@ -10,6 +10,10 @@ void* operator new (uint32_t size) {
return Global::allocator->allocate(size);
}
void* operator new (uint32_t size, void* ptr) {
return ptr;
}
void operator delete (void* ptr) {
Global::allocator->deallocate((uint32_t)ptr);
}

View File

@ -14,6 +14,7 @@ namespace Global {
}
void* operator new (uint32_t size);
void* operator new (uint32_t size, void* ptr);
void operator delete (void* ptr);
void operator delete (void* ptr, unsigned int size);

View File

@ -38,6 +38,7 @@ __attribute__((interrupt)) void gpf(interrupt_frame* frame, uint32_t err_code) {
__attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
asm ("cli"); // Disable interrupts whilst handling the context switch.
asm ("pusha"); // Push registers to the stack
//asm ("pushf"); // Push flags to the stack
Process* currentProc = Global::currentProc;
Process* nextProc = 0;
@ -90,20 +91,14 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr));
// Restore ESP of the new process.
asm volatile ("mov %0, %%esp" : : "m" (Global::kernel->processes.start->elem->esp));
// Restore registers
asm ("popa");
// Restore the initial eax
asm ("mov -0xc(%ebp), %eax");
//asm ("popf"); // Pop flags
asm ("popa"); // Restore registers
asm ("mov -0xc(%ebp), %eax"); // Restore the initial eax
// Clear the garbage that was on the stack from previous switch_context call.
asm ("mov %ebp, %esp");
// Pop EBP
asm ("pop %ebp");
// Manually perform iret.
asm ("iret");
asm ("pop %ebp"); // Pop EBP
asm ("iret"); // Manually perform iret.
}
}

View File

@ -25,3 +25,10 @@ Process* Kernel::createProcess(char* filename) {
return p;
}
void Kernel::destroyProcess(Process* p) {
this->processes.remove(p);
this->pid_map->remove(p->PID, p);
delete p;
while (1);
}

View File

@ -20,6 +20,7 @@ public:
void init_kernel();
Process* createProcess(char* filename);
void destroyProcess(Process* p);
};
#endif

View File

@ -47,7 +47,8 @@ int main() {
Global::currentProc = &kernel;
Process* p1 = kernel.createProcess("WORLD BIN");
//Process* p2 = kernel.createProcess("HELLO BIN");
Process* p2 = kernel.createProcess("HELLO BIN");
kernel.destroyProcess(p2);
init_keyboard();

View File

@ -19,6 +19,10 @@ PageMap::PageMap() {
memset(this->pagemap, 131072, 0xff);
}
PageMap::~PageMap() {
delete pagemap;
}
void PageMap::set_bit(uint32_t index) {
uint32_t offset = index % 8;
uint32_t i = index / 8;
@ -96,6 +100,10 @@ PageTable::PageTable(){
page_table = (PTE*)virt_addr;
}
PageTable::~PageTable() {
delete page_table;
}
void PageTable::map_table(uint32_t index, uint32_t addr) {
page_table[index] = (PTE){
.present = 1,
@ -139,7 +147,7 @@ PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t o
for (int i=0; i<1024; i++) {
uint32_t table_phys_addr = page_directory[i].getPhysicalPTAddress();
page_tables[i] = PageTable(table_phys_addr >> 12, table_phys_addr + offset);
new (page_tables + i) PageTable(table_phys_addr >> 12, table_phys_addr + offset);
}
}
@ -153,11 +161,18 @@ PageDirectory::PageDirectory() {
this->phys_addr = Global::allocator->virtual_to_physical(this->page_directory);
}
PageDirectory::~PageDirectory() {
for (int i=0; i<1024; i++)
if (page_tables[i].virt_addr)
page_tables[i].~PageTable();
delete page_directory;
}
void PageDirectory::map(uint32_t phys, uint32_t virt) {
split_addr* split = (split_addr*)&virt;
if (!page_tables[split->pd_index].virt_addr)
page_tables[split->pd_index] = PageTable();
new (page_tables + split->pd_index) PageTable();
page_directory[split->pd_index] = (PDE){
.present = 1,
@ -209,6 +224,11 @@ Allocator::Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt
this->virt_alloc_base = virt_alloc_base;
}
Allocator::~Allocator() {
delete virt;
delete PD;
}
void* Allocator::allocate(uint32_t size) {
uint32_t count = (size + (4096 - size % 4096)) / 4096;

View File

@ -22,6 +22,8 @@ public:
PageMap(uint32_t map);
PageMap();
~PageMap();
void mark_unavailable(uint32_t address);
void mark_unavailable(uint32_t address, uint32_t count);
@ -43,6 +45,8 @@ struct PageTable {
PageTable(uint32_t phys, uint32_t virt);
PageTable();
~PageTable(); // Delete page_table
void map_table(uint32_t index, uint32_t addr);
void unmap_table(uint32_t index);
@ -62,6 +66,8 @@ public:
PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset);
PageDirectory();
~PageDirectory(); // Delete the page tables and page_directory
void map(uint32_t phys, uint32_t virt);
void unmap(uint32_t virt);
@ -81,6 +87,9 @@ public:
Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base);
~Allocator(); // Delete virt and PD
virtual void* allocate(uint32_t size);
virtual void deallocate(uint32_t virt_addr);

View File

@ -5,7 +5,7 @@ AllocTracker::AllocTracker(void* base, uint32_t size, uint32_t count) : page_bas
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> Process::get_alloc_tracker(uint32_t address) {
xnoe::linkedlistelem<AllocTracker>* current = this->allocations.start;
while (current) {
if (current->elem.page_base < address && (current->elem.page_base + 4096 * current->elem.page_size) > address) {
if (current->elem.page_base <= address && (current->elem.page_base + 4096 * current->elem.page_size) > address) {
return xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*>(current);
}
current = current->next;
@ -87,6 +87,19 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha
asm ("mov %0, %%cr3" : : "r" (pCR3));
}
Process::~Process() {
xnoe::linkedlistelem<AllocTracker>* next = allocations.start;
while (next) {
xnoe::linkedlistelem<AllocTracker>* active = next;
next = next->next;
printf("Deleted %x\n", active->elem.page_base);
this->deallocate(active->elem.page_base+1);
}
this->deallocate(stack);
}
void* Process::allocate(uint32_t size) {
bool switched_PD = false;
uint32_t pCR3;

View File

@ -38,6 +38,8 @@ public:
Process(uint32_t PID);
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename);
~Process(); // Iterate through allocations and free those; delete stack
void* allocate(uint32_t size) override;
void deallocate(uint32_t virt_addr) override;