00001 /* Checks that when the alarm clock wakes up threads, the 00002 higher-priority threads run first. */ 00003 00004 #include <stdio.h> 00005 #include "tests/threads/tests.h" 00006 #include "threads/init.h" 00007 #include "threads/malloc.h" 00008 #include "threads/synch.h" 00009 #include "threads/thread.h" 00010 #include "devices/timer.h" 00011 00012 static thread_func alarm_priority_thread; 00013 static int64_t wake_time; 00014 static struct semaphore wait_sema; 00015 00016 void 00017 test_alarm_priority (void) 00018 { 00019 int i; 00020 00021 /* This test does not work with the MLFQS. */ 00022 ASSERT (!thread_mlfqs); 00023 00024 wake_time = timer_ticks () + 5 * TIMER_FREQ; 00025 sema_init (&wait_sema, 0); 00026 00027 for (i = 0; i < 10; i++) 00028 { 00029 int priority = PRI_DEFAULT - (i + 5) % 10 - 1; 00030 char name[16]; 00031 snprintf (name, sizeof name, "priority %d", priority); 00032 thread_create (name, priority, alarm_priority_thread, NULL); 00033 } 00034 00035 thread_set_priority (PRI_MIN); 00036 00037 for (i = 0; i < 10; i++) 00038 sema_down (&wait_sema); 00039 } 00040 00041 static void 00042 alarm_priority_thread (void *aux UNUSED) 00043 { 00044 /* Busy-wait until the current time changes. */ 00045 int64_t start_time = timer_ticks (); 00046 while (timer_elapsed (start_time) == 0) 00047 continue; 00048 00049 /* Now we know we're at the very beginning of a timer tick, so 00050 we can call timer_sleep() without worrying about races 00051 between checking the time and a timer interrupt. */ 00052 timer_sleep (wake_time - timer_ticks ()); 00053 00054 /* Print a message on wake-up. */ 00055 msg ("Thread %s woke up.", thread_name ()); 00056 00057 sema_up (&wait_sema); 00058 }