added proper accounting of user used page frames
This commit is contained in:
parent
5c4e1cee4f
commit
42571eb4eb
3 changed files with 18 additions and 10 deletions
|
@ -33,6 +33,8 @@
|
|||
* This file contains the several functions to manage the page tables
|
||||
*/
|
||||
|
||||
#include <eduos/tasks_types.h>
|
||||
|
||||
#ifndef __PAGE_H__
|
||||
#define __PAGE_H__
|
||||
|
||||
|
@ -135,7 +137,7 @@ int page_unmap(size_t viraddr, size_t npages);
|
|||
* @retval 0 Success. Everything went fine.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int page_map_copy(size_t dest);
|
||||
int page_map_copy(task_t *dest);
|
||||
|
||||
/** @brief Free a whole page map tree */
|
||||
int page_map_drop();
|
||||
|
|
|
@ -105,6 +105,9 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
|
|||
if (BUILTIN_EXPECT(!phyaddr, 0))
|
||||
goto out;
|
||||
|
||||
if (bits & PG_USER)
|
||||
atomic_int32_inc(¤t_task->user_usage);
|
||||
|
||||
/* Reference the new table within its parent */
|
||||
self[lvl][vpn] = phyaddr | bits | PG_PRESENT;
|
||||
|
||||
|
@ -158,12 +161,13 @@ int page_map_drop()
|
|||
void traverse(int lvl, long vpn) {
|
||||
long stop;
|
||||
for (stop=vpn+PAGE_MAP_ENTRIES; vpn<stop; vpn++) {
|
||||
if (self[lvl][vpn] & PG_PRESENT && self[lvl][vpn] & PG_USER) {
|
||||
if ((self[lvl][vpn] & PG_PRESENT) && (self[lvl][vpn] & PG_USER)) {
|
||||
/* Post-order traversal */
|
||||
if (lvl)
|
||||
traverse(lvl-1, vpn<<PAGE_MAP_BITS);
|
||||
|
||||
put_pages(self[lvl][vpn] & PAGE_MASK, 1);
|
||||
atomic_int32_dec(¤t_task->user_usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +181,7 @@ int page_map_drop()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int page_map_copy(size_t dest)
|
||||
int page_map_copy(task_t *dest)
|
||||
{
|
||||
int traverse(int lvl, long vpn) {
|
||||
long stop;
|
||||
|
@ -188,6 +192,8 @@ int page_map_copy(size_t dest)
|
|||
if (BUILTIN_EXPECT(!phyaddr, 0))
|
||||
return -ENOMEM;
|
||||
|
||||
atomic_int32_inc(&dest->user_usage);
|
||||
|
||||
other[lvl][vpn] = phyaddr | (self[lvl][vpn] & ~PAGE_MASK);
|
||||
if (lvl) /* PML4, PDPT, PGD */
|
||||
traverse(lvl-1, vpn<<PAGE_MAP_BITS); /* Pre-order traversal */
|
||||
|
|
|
@ -122,7 +122,7 @@ static void NORETURN do_exit(int arg)
|
|||
|
||||
kprintf("Terminate task: %u, return value %d\n", curr_task->id, arg);
|
||||
|
||||
page_map_drop();
|
||||
page_map_drop();
|
||||
|
||||
curr_task->status = TASK_FINISHED;
|
||||
reschedule();
|
||||
|
@ -204,13 +204,13 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
|
|||
spinlock_irqsave_init(&task_table[i].page_lock);
|
||||
atomic_int32_set(&task_table[i].user_usage, 0);
|
||||
|
||||
/* Allocated new PGD or PML4 and copy page table */
|
||||
size_t map = get_pages(1);
|
||||
if (BUILTIN_EXPECT(!map, 0))
|
||||
goto out;
|
||||
/* Allocated new PGD or PML4 and copy page table */
|
||||
task_table[i].page_map = get_pages(1);
|
||||
if (BUILTIN_EXPECT(!task_table[i].page_map, 0))
|
||||
goto out;
|
||||
|
||||
page_map_copy(map);
|
||||
task_table[i].page_map = map;
|
||||
/* Copy page tables & user frames of current task to new one */
|
||||
page_map_copy(&task_table[i]);
|
||||
|
||||
if (id)
|
||||
*id = i;
|
||||
|
|
Loading…
Add table
Reference in a new issue