From 4ae5b813663cd56fcbe1f1f547c9d445e5dc6107 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 17 Sep 2004 06:52:27 +0000 Subject: [PATCH] Add thread priority support. --- src/threads/synch.c | 2 +- src/threads/test.c | 2 +- src/threads/thread.c | 71 +++++++++++++++++++++++++------------------- src/threads/thread.h | 16 +++++++--- 4 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/threads/synch.c b/src/threads/synch.c index be8f0a5..28696d4 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -117,7 +117,7 @@ sema_self_test (void) printf ("Testing semaphores..."); sema_init (&sema[0], 0, "ping"); sema_init (&sema[1], 0, "pong"); - thread_create ("sema-test", sema_test_helper, &sema); + thread_create ("sema-test", PRI_DEFAULT, sema_test_helper, &sema); for (i = 0; i < 10; i++) { sema_up (&sema[0]); diff --git a/src/threads/test.c b/src/threads/test.c index 4c7bfed..ae9d16d 100644 --- a/src/threads/test.c +++ b/src/threads/test.c @@ -63,7 +63,7 @@ test_sleep (int iterations) t->product = &product; t->lock = &lock; sema_init (&t->done, 0, name); - t->tid = thread_create (name, sleeper, t); + t->tid = thread_create (name, PRI_DEFAULT, sleeper, t); } /* Wait for all the threads to finish. */ diff --git a/src/threads/thread.c b/src/threads/thread.c index a1c98a6..8a55699 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -45,8 +45,8 @@ static void kernel_thread (thread_func *, void *aux); static void idle (void *aux UNUSED); static struct thread *running_thread (void); static struct thread *next_thread_to_run (void); -static struct thread *new_thread (const char *name); -static void init_thread (struct thread *, const char *name); +static struct thread *new_thread (const char *name, int priority); +static void init_thread (struct thread *, const char *name, int priority); static bool is_thread (struct thread *); static void *alloc_frame (struct thread *, size_t size); static void destroy_thread (struct thread *); @@ -72,7 +72,7 @@ thread_init (void) /* Set up a thread structure for the running thread. */ initial_thread = running_thread (); - init_thread (initial_thread, "main"); + init_thread (initial_thread, "main", PRI_DEFAULT); initial_thread->status = THREAD_RUNNING; initial_thread->tid = allocate_tid (); @@ -85,20 +85,26 @@ thread_init (void) void thread_start (void) { - thread_create ("idle", idle, NULL); + thread_create ("idle", PRI_DEFAULT, idle, NULL); intr_enable (); } -/* Creates a new kernel thread named NAME, which executes - FUNCTION passing AUX as the argument, and adds it to the ready - queue. If thread_start() has been called, then the new thread - may be scheduled before thread_create() returns. It could - even exit before thread_create() returns. Use a semaphore or - some other form of synchronization if you need to ensure - ordering. Returns the thread identifier for the new thread, - or TID_ERROR if creation fails. */ +/* Creates a new kernel thread named NAME with the given initial + PRIORITY, which executes FUNCTION passing AUX as the argument, + and adds it to the ready queue. If thread_start() has been + called, then the new thread may be scheduled before + thread_create() returns. It could even exit before + thread_create() returns. Use a semaphore or some other form + of synchronization if you need to ensure ordering. Returns + the thread identifier for the new thread, or TID_ERROR if + creation fails. + + The code provided sets the new thread's `priority' member to + PRIORITY, but no actual priority scheduling is implemented. + Priority scheduling is the goal of Problem 1-3. */ tid_t -thread_create (const char *name, thread_func *function, void *aux) +thread_create (const char *name, int priority, + thread_func *function, void *aux) { struct thread *t; struct kernel_thread_frame *kf; @@ -108,10 +114,10 @@ thread_create (const char *name, thread_func *function, void *aux) ASSERT (function != NULL); - t = new_thread (name); + t = new_thread (name, priority); if (t == NULL) return TID_ERROR; - tid = t->tid = allocate_tid (); + tid = t->tid; /* Stack frame for kernel_thread(). */ kf = alloc_frame (t, sizeof *kf); @@ -150,10 +156,10 @@ thread_execute (const char *filename) ASSERT (filename != NULL); - t = new_thread (filename); + t = new_thread (filename, PRI_DEFAULT); if (t == NULL) return TID_ERROR; - tid = t->tid = allocate_tid (); + tid = t->tid; if (!addrspace_load (t, filename, &start)) PANIC ("%s: program load failed", filename); @@ -331,31 +337,36 @@ is_thread (struct thread *t) return t != NULL && t->magic == THREAD_MAGIC; } -/* Creates a new thread named NAME and initializes its fields. - Returns the new thread if successful or a null pointer on - failure. */ +/* Creates a new thread named NAME as a child of the running + thread. Returns the new thread if successful or a null + pointer on failure. */ static struct thread * -new_thread (const char *name) +new_thread (const char *name, int priority) { - struct thread *t; - - ASSERT (name != NULL); - - t = palloc_get (PAL_ZERO); - if (t != NULL) - init_thread (t, name); + struct thread *t = palloc_get (PAL_ZERO); + if (t != NULL) + { + init_thread (t, name, priority); + t->tid = allocate_tid (); + } return t; } -/* Initializes T as a new, blocked thread named NAME. */ +/* Does basic initialization of T as a new, blocked thread named + NAME. */ static void -init_thread (struct thread *t, const char *name) +init_thread (struct thread *t, const char *name, int priority) { + ASSERT (t != NULL); + ASSERT (PRI_MIN <= priority && priority <= PRI_MAX); + ASSERT (name != NULL); + memset (t, 0, sizeof *t); t->status = THREAD_BLOCKED; strlcpy (t->name, name, sizeof t->name); t->stack = (uint8_t *) t + PGSIZE; + t->priority = priority; t->magic = THREAD_MAGIC; } diff --git a/src/threads/thread.h b/src/threads/thread.h index e844b5c..0480293 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -23,6 +23,11 @@ enum thread_status typedef int tid_t; #define TID_ERROR ((tid_t) -1) /* Error value for tid_t. */ +/* Thread priorities. */ +#define PRI_MIN 0 /* Lowest priority. */ +#define PRI_DEFAULT 29 /* Default priority. */ +#define PRI_MAX 59 /* Highest priority. */ + /* A kernel thread or user process. Each thread structure is stored in its own 4 kB page. The @@ -86,6 +91,7 @@ struct thread enum thread_status status; /* Thread state. */ char name[16]; /* Name (for debugging purposes). */ uint8_t *stack; /* Saved stack pointer. */ + int priority; /* Priority. */ /* Shared between thread.c and synch.c. */ list_elem elem; /* List element. */ @@ -103,7 +109,7 @@ void thread_init (void); void thread_start (void); typedef void thread_func (void *aux); -tid_t thread_create (const char *name, thread_func *, void *); +tid_t thread_create (const char *name, int priority, thread_func *, void *); #ifdef USERPROG tid_t thread_execute (const char *filename); #endif @@ -117,9 +123,11 @@ void thread_exit (void) NO_RETURN; void thread_yield (void); void thread_block (void); -/* These functions will be implemented in project 1. */ +/* This function will be implemented in problem 1-2. */ void thread_join (tid_t); -void thread_set_priority (tid_t, int); -int thread_get_priority (tid_t); + +/* These functions will be implemented in problem 1-3. */ +void thread_set_priority (int); +int thread_get_priority (void); #endif /* threads/thread.h */ -- 2.30.2