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 }