X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthreads%2Fthread.c;h=dc23efb4b2dfb3bb608084940991a3c916d50ae6;hb=d91529429c5d65d66444e5c4f8d323cea6306878;hp=02f3c7b62bb1f949a3a739be3bad3367591fb33c;hpb=7fd56df9056d6442d52f23d3fb356010b988668d;p=pintos-anon diff --git a/src/threads/thread.c b/src/threads/thread.c index 02f3c7b..dc23efb 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -46,13 +46,17 @@ static long long idle_ticks; /* # of timer ticks spent idle. */ static long long kernel_ticks; /* # of timer ticks in kernel threads. */ static long long user_ticks; /* # of timer ticks in user programs. */ +/* Scheduling. */ +#define TIME_SLICE 4 /* # of timer ticks to give each thread. */ +static unsigned thread_ticks; /* # of timer ticks since last yield. */ + 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 void init_thread (struct thread *, const char *name, int priority); -static bool is_thread (struct thread *); +static bool is_thread (struct thread *) UNUSED; static void *alloc_frame (struct thread *, size_t size); static void schedule (void); void schedule_tail (struct thread *prev); @@ -73,7 +77,7 @@ thread_init (void) { ASSERT (intr_get_level () == INTR_OFF); - lock_init (&tid_lock, "tid"); + lock_init (&tid_lock); list_init (&ready_list); /* Set up a thread structure for the running thread. */ @@ -88,16 +92,17 @@ thread_init (void) void thread_start (void) { - thread_create ("idle", PRI_DEFAULT, idle, NULL); + thread_create ("idle", PRI_MAX, idle, NULL); intr_enable (); } -/* Called by the timer interrupt handler at each timer tick to - update statistics. */ +/* Called by the timer interrupt handler at each timer tick. */ void thread_tick (void) { struct thread *t = thread_current (); + + /* Update statistics. */ if (t == idle_thread) idle_ticks++; #ifdef USERPROG @@ -106,6 +111,10 @@ thread_tick (void) #endif else kernel_ticks++; + + /* Enforce preemption. */ + if (++thread_ticks >= TIME_SLICE) + intr_yield_on_return (); } /* Prints thread statistics. */ @@ -287,6 +296,37 @@ thread_get_priority (void) { return thread_current ()->priority; } + +/* Sets the current thread's nice value to NICE. */ +void +thread_set_nice (int nice UNUSED) +{ + /* Not yet implemented. */ +} + +/* Returns the current thread's nice value. */ +int +thread_get_nice (void) +{ + /* Not yet implemented. */ + return 0; +} + +/* Returns 100 times the system load average. */ +int +thread_get_load_avg (void) +{ + /* Not yet implemented. */ + return 0; +} + +/* Returns 100 times the current thread's recent_cpu value. */ +int +thread_get_recent_cpu (void) +{ + /* Not yet implemented. */ + return 0; +} /* Idle thread. Executes when no other thread is ready to run. */ static void @@ -336,13 +376,13 @@ running_thread (void) down to the start of a page. Because `struct thread' is always at the beginning of a page and the stack pointer is somewhere in the middle, this locates the curent thread. */ - asm ("mov %0, %%esp" : "=g" (esp)); + asm ("mov %%esp, %0" : "=g" (esp)); return pg_round_down (esp); } /* Returns true if T appears to point to a valid thread. */ static bool -is_thread (struct thread *t) +is_thread (struct thread *t) { return t != NULL && t->magic == THREAD_MAGIC; } @@ -417,6 +457,9 @@ schedule_tail (struct thread *prev) /* Mark us as running. */ cur->status = THREAD_RUNNING; + /* Start new time slice. */ + thread_ticks = 0; + #ifdef USERPROG /* Activate the new address space. */ process_activate ();