feat: implement frame table without thread safety
This commit is contained in:
@@ -24,6 +24,9 @@
|
||||
#include "threads/vaddr.h"
|
||||
#include "threads/synch.h"
|
||||
#include "devices/timer.h"
|
||||
#ifdef VM
|
||||
#include "vm/frame.h"
|
||||
#endif
|
||||
|
||||
/* Defines the native number of bytes processed by the processor
|
||||
(for the purposes of alignment). */
|
||||
@@ -113,7 +116,10 @@ process_execute (const char *cmd)
|
||||
return tid;
|
||||
}
|
||||
|
||||
static void *get_usr_kpage (enum palloc_flags flags);
|
||||
static void free_usr_kpage (void *kpage);
|
||||
static bool install_page (void *upage, void *kpage, bool writable);
|
||||
|
||||
static bool process_init_stack (char *cmd_saveptr, void **esp, char *file_name);
|
||||
static void *push_to_stack (void **esp, void *data, size_t data_size);
|
||||
#define push_var_to_stack(esp, var) (push_to_stack (esp, &var, sizeof (var)))
|
||||
@@ -253,7 +259,7 @@ process_init_stack (char *cmd_saveptr, void **esp, char *file_name)
|
||||
/* Allocate the pages and map them to the user process. */
|
||||
for (int i = 1; i < pages_needed + 1; i++)
|
||||
{
|
||||
uint8_t *kpage = palloc_get_page (PAL_USER | PAL_ZERO);
|
||||
uint8_t *kpage = get_usr_kpage (PAL_ZERO);
|
||||
if (!install_page (((uint8_t *) PHYS_BASE) - PGSIZE * (i + 1),
|
||||
kpage, true))
|
||||
return false;
|
||||
@@ -704,7 +710,7 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
|
||||
if (kpage == NULL){
|
||||
|
||||
/* Get a new page of memory. */
|
||||
kpage = palloc_get_page (PAL_USER);
|
||||
kpage = get_usr_kpage (0);
|
||||
if (kpage == NULL){
|
||||
return false;
|
||||
}
|
||||
@@ -712,7 +718,7 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
|
||||
/* Add the page to the process's address space. */
|
||||
if (!install_page (upage, kpage, writable))
|
||||
{
|
||||
palloc_free_page (kpage);
|
||||
free_usr_kpage (kpage);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -747,18 +753,44 @@ setup_stack (void **esp)
|
||||
uint8_t *kpage;
|
||||
bool success = false;
|
||||
|
||||
kpage = palloc_get_page (PAL_USER | PAL_ZERO);
|
||||
kpage = get_usr_kpage (PAL_ZERO);
|
||||
if (kpage != NULL)
|
||||
{
|
||||
success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true);
|
||||
if (success)
|
||||
*esp = PHYS_BASE;
|
||||
else
|
||||
palloc_free_page (kpage);
|
||||
free_usr_kpage (kpage);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/* Claims a page from the user pool and returns its kernel address,
|
||||
updating the frame table if VM is enabled. */
|
||||
static void *
|
||||
get_usr_kpage (enum palloc_flags flags)
|
||||
{
|
||||
void *page;
|
||||
#ifdef VM
|
||||
page = frame_alloc (flags);
|
||||
#else
|
||||
page = palloc_get_page (flags | PAL_USER);
|
||||
#endif
|
||||
return page;
|
||||
}
|
||||
|
||||
/* Frees a page belonging to a user process given its kernel address,
|
||||
updating the frame table if VM is enabled. */
|
||||
static void
|
||||
free_usr_kpage (void *kpage)
|
||||
{
|
||||
#ifdef VM
|
||||
frame_free (kpage);
|
||||
#else
|
||||
palloc_free_page (kpage);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Adds a mapping from user virtual address UPAGE to kernel
|
||||
virtual address KPAGE to the page table.
|
||||
If WRITABLE is true, the user process may modify the page;
|
||||
|
||||
Reference in New Issue
Block a user