00001 
00002 
00003 
00004 
00005 #include <stdio.h>
00006 #include "tests/threads/tests.h"
00007 #include "threads/init.h"
00008 #include "threads/malloc.h"
00009 #include "threads/synch.h"
00010 #include "threads/thread.h"
00011 #include "devices/timer.h"
00012 
00013 static void test_sleep (int thread_cnt, int iterations);
00014 
00015 void
00016 test_alarm_simultaneous (void) 
00017 {
00018   test_sleep (3, 5);
00019 }
00020 
00021 
00022 struct sleep_test 
00023   {
00024     int64_t start;              
00025     int iterations;             
00026     int *output_pos;            
00027   };
00028 
00029 static void sleeper (void *);
00030 
00031 
00032 static void
00033 test_sleep (int thread_cnt, int iterations) 
00034 {
00035   struct sleep_test test;
00036   int *output;
00037   int i;
00038 
00039   
00040   ASSERT (!thread_mlfqs);
00041 
00042   msg ("Creating %d threads to sleep %d times each.", thread_cnt, iterations);
00043   msg ("Each thread sleeps 10 ticks each time.");
00044   msg ("Within an iteration, all threads should wake up on the same tick.");
00045 
00046   
00047   output = malloc (sizeof *output * iterations * thread_cnt * 2);
00048   if (output == NULL)
00049     PANIC ("couldn't allocate memory for test");
00050 
00051   
00052   test.start = timer_ticks () + 100;
00053   test.iterations = iterations;
00054   test.output_pos = output;
00055 
00056   
00057   ASSERT (output != NULL);
00058   for (i = 0; i < thread_cnt; i++)
00059     {
00060       char name[16];
00061       snprintf (name, sizeof name, "thread %d", i);
00062       thread_create (name, PRI_DEFAULT, sleeper, &test);
00063     }
00064   
00065   
00066   timer_sleep (100 + iterations * 10 + 100);
00067 
00068   
00069   msg ("iteration 0, thread 0: woke up after %d ticks", output[0]);
00070   for (i = 1; i < test.output_pos - output; i++) 
00071     msg ("iteration %d, thread %d: woke up %d ticks later",
00072          i / thread_cnt, i % thread_cnt, output[i] - output[i - 1]);
00073   
00074   free (output);
00075 }
00076 
00077 
00078 static void
00079 sleeper (void *test_) 
00080 {
00081   struct sleep_test *test = test_;
00082   int i;
00083 
00084   
00085   timer_sleep (1);
00086 
00087   for (i = 1; i <= test->iterations; i++) 
00088     {
00089       int64_t sleep_until = test->start + i * 10;
00090       timer_sleep (sleep_until - timer_ticks ());
00091       *test->output_pos++ = timer_ticks () - test->start;
00092       thread_yield ();
00093     }
00094 }