fix: synchronise pagedir which now may be accessed by other threads, with a lock

This commit is contained in:
2024-12-06 18:22:00 +00:00
parent 77fedd6666
commit ce89d3577f
8 changed files with 78 additions and 26 deletions

View File

@@ -50,7 +50,7 @@ hash_less_func frame_metadata_less;
static struct list_elem *lru_next (struct list_elem *e);
static struct list_elem *lru_prev (struct list_elem *e);
static struct frame_metadata *frame_metadata_get (void *frame);
static struct frame_metadata *get_victim (void);
static struct frame_metadata *get_victim (struct thread *cur);
static void free_owners (struct list *owners);
static struct frame_metadata *frame_metadata_find (void *frame);
@@ -91,7 +91,7 @@ frame_alloc (enum palloc_flags flags, void *upage, struct thread *owner)
if (next_victim == NULL)
PANIC ("Couldn't allocate a single page to main memory!\n");
struct frame_metadata *victim = get_victim ();
struct frame_metadata *victim = get_victim (owner);
ASSERT (victim != NULL); /* get_victim () should never return null. */
/* 2. Handle victim page writing based on its type. */
@@ -111,7 +111,7 @@ frame_alloc (enum palloc_flags flags, void *upage, struct thread *owner)
else
{
/* Otherwise, insert the page into swap. */
page_insert_swapped (victim->upage, victim->frame, &victim->owners);
page_insert_swapped (victim->upage, victim->frame, &victim->owners, owner);
}
/* Free victim's owners. */
@@ -290,7 +290,7 @@ frame_metadata_find (void *frame)
/* A pre-condition for calling this function is that the calling thread
owns ftable_lock and that lru_list is non-empty. */
static struct frame_metadata *
get_victim (void)
get_victim (struct thread *cur)
{
struct list_elem *ve = next_victim;
struct frame_metadata *frame_metadata;
@@ -312,6 +312,8 @@ get_victim (void)
{
struct frame_owner *frame_owner
= list_entry (oe, struct frame_owner, elem);
if (frame_owner->owner != cur)
lock_acquire (&frame_owner->owner->pagedir_lock);
uint32_t *pd = frame_owner->owner->pagedir;
void *upage = frame_metadata->upage;
@@ -320,6 +322,8 @@ get_victim (void)
found = false;
pagedir_set_accessed (pd, upage, false);
}
if (frame_owner->owner != cur)
lock_release (&frame_owner->owner->pagedir_lock);
}
}