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;
|
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);
|
return Global::allocator->allocate(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* operator new (uint32_t size, void* ptr) {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
void operator delete (void* ptr) {
|
void operator delete (void* ptr) {
|
||||||
Global::allocator->deallocate((uint32_t)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* operator new (uint32_t size, void* ptr);
|
||||||
void operator delete (void* ptr);
|
void operator delete (void* ptr);
|
||||||
void operator delete (void* ptr, unsigned int size);
|
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) {
|
__attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
|
||||||
asm ("cli"); // Disable interrupts whilst handling the context switch.
|
asm ("cli"); // Disable interrupts whilst handling the context switch.
|
||||||
asm ("pusha"); // Push registers to the stack
|
asm ("pusha"); // Push registers to the stack
|
||||||
|
//asm ("pushf"); // Push flags to the stack
|
||||||
|
|
||||||
Process* currentProc = Global::currentProc;
|
Process* currentProc = Global::currentProc;
|
||||||
Process* nextProc = 0;
|
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));
|
asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr));
|
||||||
// Restore ESP of the new process.
|
// Restore ESP of the new process.
|
||||||
asm volatile ("mov %0, %%esp" : : "m" (Global::kernel->processes.start->elem->esp));
|
asm volatile ("mov %0, %%esp" : : "m" (Global::kernel->processes.start->elem->esp));
|
||||||
// Restore registers
|
|
||||||
asm ("popa");
|
|
||||||
|
|
||||||
// Restore the initial eax
|
//asm ("popf"); // Pop flags
|
||||||
asm ("mov -0xc(%ebp), %eax");
|
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.
|
// Clear the garbage that was on the stack from previous switch_context call.
|
||||||
asm ("mov %ebp, %esp");
|
asm ("mov %ebp, %esp");
|
||||||
|
asm ("pop %ebp"); // Pop EBP
|
||||||
// Pop EBP
|
asm ("iret"); // Manually perform iret.
|
||||||
asm ("pop %ebp");
|
|
||||||
|
|
||||||
// Manually perform iret.
|
|
||||||
asm ("iret");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,4 +24,11 @@ Process* Kernel::createProcess(char* filename) {
|
|||||||
this->processes.append(p);
|
this->processes.append(p);
|
||||||
|
|
||||||
return 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();
|
void init_kernel();
|
||||||
|
|
||||||
Process* createProcess(char* filename);
|
Process* createProcess(char* filename);
|
||||||
|
void destroyProcess(Process* p);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -47,7 +47,8 @@ int main() {
|
|||||||
Global::currentProc = &kernel;
|
Global::currentProc = &kernel;
|
||||||
|
|
||||||
Process* p1 = kernel.createProcess("WORLD BIN");
|
Process* p1 = kernel.createProcess("WORLD BIN");
|
||||||
//Process* p2 = kernel.createProcess("HELLO BIN");
|
Process* p2 = kernel.createProcess("HELLO BIN");
|
||||||
|
kernel.destroyProcess(p2);
|
||||||
|
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
|
|
||||||
|
@ -19,6 +19,10 @@ PageMap::PageMap() {
|
|||||||
memset(this->pagemap, 131072, 0xff);
|
memset(this->pagemap, 131072, 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageMap::~PageMap() {
|
||||||
|
delete pagemap;
|
||||||
|
}
|
||||||
|
|
||||||
void PageMap::set_bit(uint32_t index) {
|
void PageMap::set_bit(uint32_t index) {
|
||||||
uint32_t offset = index % 8;
|
uint32_t offset = index % 8;
|
||||||
uint32_t i = index / 8;
|
uint32_t i = index / 8;
|
||||||
@ -96,6 +100,10 @@ PageTable::PageTable(){
|
|||||||
page_table = (PTE*)virt_addr;
|
page_table = (PTE*)virt_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageTable::~PageTable() {
|
||||||
|
delete page_table;
|
||||||
|
}
|
||||||
|
|
||||||
void PageTable::map_table(uint32_t index, uint32_t addr) {
|
void PageTable::map_table(uint32_t index, uint32_t addr) {
|
||||||
page_table[index] = (PTE){
|
page_table[index] = (PTE){
|
||||||
.present = 1,
|
.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++) {
|
for (int i=0; i<1024; i++) {
|
||||||
uint32_t table_phys_addr = page_directory[i].getPhysicalPTAddress();
|
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);
|
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) {
|
void PageDirectory::map(uint32_t phys, uint32_t virt) {
|
||||||
split_addr* split = (split_addr*)&virt;
|
split_addr* split = (split_addr*)&virt;
|
||||||
|
|
||||||
if (!page_tables[split->pd_index].virt_addr)
|
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){
|
page_directory[split->pd_index] = (PDE){
|
||||||
.present = 1,
|
.present = 1,
|
||||||
@ -209,6 +224,11 @@ Allocator::Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt
|
|||||||
this->virt_alloc_base = virt_alloc_base;
|
this->virt_alloc_base = virt_alloc_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Allocator::~Allocator() {
|
||||||
|
delete virt;
|
||||||
|
delete PD;
|
||||||
|
}
|
||||||
|
|
||||||
void* Allocator::allocate(uint32_t size) {
|
void* Allocator::allocate(uint32_t size) {
|
||||||
uint32_t count = (size + (4096 - size % 4096)) / 4096;
|
uint32_t count = (size + (4096 - size % 4096)) / 4096;
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@ public:
|
|||||||
PageMap(uint32_t map);
|
PageMap(uint32_t map);
|
||||||
PageMap();
|
PageMap();
|
||||||
|
|
||||||
|
~PageMap();
|
||||||
|
|
||||||
void mark_unavailable(uint32_t address);
|
void mark_unavailable(uint32_t address);
|
||||||
void mark_unavailable(uint32_t address, uint32_t count);
|
void mark_unavailable(uint32_t address, uint32_t count);
|
||||||
|
|
||||||
@ -43,6 +45,8 @@ struct PageTable {
|
|||||||
PageTable(uint32_t phys, uint32_t virt);
|
PageTable(uint32_t phys, uint32_t virt);
|
||||||
PageTable();
|
PageTable();
|
||||||
|
|
||||||
|
~PageTable(); // Delete page_table
|
||||||
|
|
||||||
void map_table(uint32_t index, uint32_t addr);
|
void map_table(uint32_t index, uint32_t addr);
|
||||||
void unmap_table(uint32_t index);
|
void unmap_table(uint32_t index);
|
||||||
|
|
||||||
@ -62,6 +66,8 @@ public:
|
|||||||
PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset);
|
PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset);
|
||||||
PageDirectory();
|
PageDirectory();
|
||||||
|
|
||||||
|
~PageDirectory(); // Delete the page tables and page_directory
|
||||||
|
|
||||||
void map(uint32_t phys, uint32_t virt);
|
void map(uint32_t phys, uint32_t virt);
|
||||||
void unmap(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* phys, PageMap* virt, uint32_t virt_alloc_base);
|
||||||
Allocator(PageDirectory* page_directory, 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* allocate(uint32_t size);
|
||||||
virtual void deallocate(uint32_t virt_addr);
|
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::Maybe<xnoe::linkedlistelem<AllocTracker>*> Process::get_alloc_tracker(uint32_t address) {
|
||||||
xnoe::linkedlistelem<AllocTracker>* current = this->allocations.start;
|
xnoe::linkedlistelem<AllocTracker>* current = this->allocations.start;
|
||||||
while (current) {
|
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);
|
return xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*>(current);
|
||||||
}
|
}
|
||||||
current = current->next;
|
current = current->next;
|
||||||
@ -87,6 +87,19 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha
|
|||||||
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
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) {
|
void* Process::allocate(uint32_t size) {
|
||||||
bool switched_PD = false;
|
bool switched_PD = false;
|
||||||
uint32_t pCR3;
|
uint32_t pCR3;
|
||||||
|
@ -38,6 +38,8 @@ public:
|
|||||||
Process(uint32_t PID);
|
Process(uint32_t PID);
|
||||||
Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename);
|
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* allocate(uint32_t size) override;
|
||||||
void deallocate(uint32_t virt_addr) override;
|
void deallocate(uint32_t virt_addr) override;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user