Compare commits

...

13 Commits

Author SHA1 Message Date
Demetriades, Themis
fd5143110f Merge branch 'task1/merged/priority-scheduling' into 'task1/priority-scheduling'
# Conflicts:
#   .gitignore
#   src/threads/synch.c
#   src/threads/thread.c
2024-10-17 17:58:13 +00:00
Themis Demetriades
e38e1400a2 Update singleton_sema_priority_greater function description for clarity 2024-10-17 09:24:49 +01:00
Themis Demetriades
810a5376b9 Implement priority scheduling for condition variables 2024-10-17 08:55:29 +01:00
Themis Demetriades
c32a69a368 Update repository settings to ignore shell scripts 2024-10-15 17:00:02 +01:00
Themis Demetriades
163b7f9016 Update setting of priority of threads to only yield when current thread's priority has been lowered 2024-10-15 15:38:31 +01:00
Themis Demetriades
3c1a26b668 Update setting of thread priorities to yield in case a higher priority thread requires control 2024-10-15 15:14:05 +01:00
Themis Demetriades
54b46806ba Update thread creation to yield thread in case it's no longer the highest priority 2024-10-15 15:12:01 +01:00
Themis Demetriades
6855a48603 Update semaphore code to wake highest priority thread, and run if required 2024-10-15 13:53:48 +01:00
Themis Demetriades
79061fcb9b Update thread module to maintain list of ready threads in descending order of priority 2024-10-15 13:51:41 +01:00
Themis Demetriades
d4d5a7a937 Update thread_priority_greater function signature to explicitly signal unused parameter 2024-10-15 12:01:03 +01:00
Themis Demetriades
f1fa7d2ffb Reformat thread_priority_greater to fit code style 2024-10-15 11:51:40 +01:00
Themis Demetriades
1821d73b09 Add comparison function for thread list elements based on thread priority 2024-10-15 11:50:04 +01:00
Themis Demetriades
4ed64cf173 Add guard in thread_set_priority ensuring priority values are within correct range 2024-10-15 10:47:38 +01:00
3 changed files with 51 additions and 36 deletions

View File

@@ -125,10 +125,6 @@ sema_up (struct semaphore *sema)
sema->value++;
intr_set_level (old_level);
/* If the unblocked thread has higher priority than the current running thread
then yield the CPU to the unblocked thread */
if (!intr_context() && t != NULL && t->priority > thread_get_priority ())
thread_yield ();
}
@@ -324,6 +320,38 @@ cond_init (struct condition *cond)
list_init (&cond->waiters);
}
/* Returns true iff the priority of the only thread in the first singleton
semaphore is greater than the priority of the only thread in the second
singleton semaphore.
Where this function is used for insertion in a singleton semaphore list, the
third argument may specify a list_elem * to assume corresponds to the thread
waiting for the inserting semaphore. For correctness, ensure this thread
calls sema_down () for this semaphore before future list accesses. */
static bool
singleton_sema_priority_greater (const struct list_elem *a,
const struct list_elem *b,
void *insertingThread)
{
struct list_elem *te_a, *te_b;
te_b = list_front (
&list_entry (b, struct semaphore_elem, elem)->semaphore.waiters);
if (insertingThread == NULL)
{
te_a = list_front (
&list_entry (a, struct semaphore_elem, elem)->semaphore.waiters);
}
else
{
te_a = insertingThread;
}
return thread_priority_greater (te_a, te_b, NULL);
}
/* Atomically releases LOCK and waits for COND to be signaled by
some other piece of code. After COND is signaled, LOCK is
reacquired before returning. LOCK must be held before calling

View File

@@ -219,6 +219,7 @@ thread_create (const char *name, int priority,
/* Add to run queue. */
thread_unblock (t);
thread_yield ();
/* Yield if the new thread has a higher priority than the current thread. */
if (priority > thread_get_priority ())
@@ -377,41 +378,13 @@ priority_more (const struct list_elem *a_, const struct list_elem *b_,
void
thread_set_priority (int new_priority)
{
ASSERT (new_priority >= PRI_MIN);
ASSERT (new_priority <= PRI_MAX);
ASSERT (PRI_MIN <= new_priority && new_priority <= PRI_MAX);
int old_priority = thread_get_priority ();
if (new_priority == old_priority)
return;
thread_current ()->priority = new_priority;
enum intr_level old_level = intr_disable ();
/* If the thread is in the ready list, the list must be reordered to maintain
the priority order. */
if (thread_current ()->status == THREAD_READY) {
/* Remove from the ready list and reinsert it in priority order. */
list_remove (&thread_current ()->elem);
list_insert_ordered (&ready_list, &thread_current ()->elem, priority_more,
NULL);
}
if (new_priority < old_priority && !list_empty (&ready_list)) {
/* If the new priority is lower than the old priority, check if the current
thread no longer has the highest priority. If it doesn't, yield the CPU.
*/
struct thread *next_thread =
list_entry (list_front (&ready_list), struct thread, elem);
if (next_thread->priority > new_priority) {
if (new_priority < old_priority)
thread_yield ();
}
}
intr_set_level (old_level);
}
/* Returns the current thread's priority. */
int
@@ -654,6 +627,17 @@ allocate_tid (void)
return tid;
}
/* Returns true iff the priority of the first list element's thread is greater
than that of the second list element's thread. */
bool
thread_priority_greater (const struct list_elem *a, const struct list_elem *b,
void *aux UNUSED)
{
struct thread *ta = list_entry (a, struct thread, elem);
struct thread *tb = list_entry (b, struct thread, elem);
return ta->priority > tb->priority;
}
/* Offset of `stack' member within `struct thread'.
Used by switch.S, which can't figure it out on its own. */
uint32_t thread_stack_ofs = offsetof (struct thread, stack);

View File

@@ -141,4 +141,7 @@ void thread_set_nice (int);
int thread_get_recent_cpu (void);
int thread_get_load_avg (void);
/* Returns true iff the priority of the first list element's thread is greater
than that of the second list element's thread. */
list_less_func thread_priority_greater;
#endif /* threads/thread.h */