Implemented necessary changes for Process destruction. Processes clean up their memory when deleted.
This commit is contained in:
parent
b7566ef777
commit
a9ec673b24
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,4 +24,11 @@ Process* Kernel::createProcess(char* filename) {
|
||||
this->processes.append(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void Kernel::destroyProcess(Process* p) {
|
||||
this->processes.remove(p);
|
||||
this->pid_map->remove(p->PID, p);
|
||||
delete p;
|
||||
while (1);
|
||||
}
|
@ -20,6 +20,7 @@ public:
|
||||
void init_kernel();
|
||||
|
||||
Process* createProcess(char* filename);
|
||||
void destroyProcess(Process* p);
|
||||
};
|
||||
|
||||
#endif
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user