diff options
Diffstat (limited to 'src/tests/threads/mlfqs-fair.c')
| -rw-r--r-- | src/tests/threads/mlfqs-fair.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/tests/threads/mlfqs-fair.c b/src/tests/threads/mlfqs-fair.c new file mode 100644 index 0000000..3b1bea5 --- /dev/null +++ b/src/tests/threads/mlfqs-fair.c @@ -0,0 +1,124 @@ +/* Measures the correctness of the "nice" implementation. + + The "fair" tests run either 2 or 20 threads all niced to 0. + The threads should all receive approximately the same number + of ticks. Each test runs for 30 seconds, so the ticks should + also sum to approximately 30 * 100 == 3000 ticks. + + The mlfqs-nice-2 test runs 2 threads, one with nice 0, the + other with nice 5, which should receive 1,904 and 1,096 ticks, + respectively, over 30 seconds. + + The mlfqs-nice-10 test runs 10 threads with nice 0 through 9. + They should receive 672, 588, 492, 408, 316, 232, 152, 92, 40, + and 8 ticks, respectively, over 30 seconds. + + (The above are computed via simulation in mlfqs.pm.) */ + +#include <stdio.h> +#include <inttypes.h> +#include "tests/threads/tests.h" +#include "threads/init.h" +#include "threads/malloc.h" +#include "threads/palloc.h" +#include "threads/synch.h" +#include "threads/thread.h" +#include "devices/timer.h" + +static void test_mlfqs_fair (int thread_cnt, int nice_min, int nice_step); + +void +test_mlfqs_fair_2 (void) +{ + test_mlfqs_fair (2, 0, 0); +} + +void +test_mlfqs_fair_20 (void) +{ + test_mlfqs_fair (20, 0, 0); +} + +void +test_mlfqs_nice_2 (void) +{ + test_mlfqs_fair (2, 0, 5); +} + +void +test_mlfqs_nice_10 (void) +{ + test_mlfqs_fair (10, 0, 1); +} + +#define MAX_THREAD_CNT 20 + +struct thread_info + { + int64_t start_time; + int tick_count; + int nice; + }; + +static void load_thread (void *aux); + +static void +test_mlfqs_fair (int thread_cnt, int nice_min, int nice_step) +{ + struct thread_info info[MAX_THREAD_CNT]; + int64_t start_time; + int nice; + int i; + + ASSERT (thread_mlfqs); + ASSERT (thread_cnt <= MAX_THREAD_CNT); + ASSERT (nice_min >= -10); + ASSERT (nice_step >= 0); + ASSERT (nice_min + nice_step * (thread_cnt - 1) <= 20); + + thread_set_nice (-20); + + start_time = timer_ticks (); + msg ("Starting %d threads...", thread_cnt); + nice = nice_min; + for (i = 0; i < thread_cnt; i++) + { + struct thread_info *ti = &info[i]; + char name[16]; + + ti->start_time = start_time; + ti->tick_count = 0; + ti->nice = nice; + + snprintf(name, sizeof name, "load %d", i); + thread_create (name, PRI_DEFAULT, load_thread, ti); + + nice += nice_step; + } + msg ("Starting threads took %"PRId64" ticks.", timer_elapsed (start_time)); + + msg ("Sleeping 40 seconds to let threads run, please wait..."); + timer_sleep (40 * TIMER_FREQ); + + for (i = 0; i < thread_cnt; i++) + msg ("Thread %d received %d ticks.", i, info[i].tick_count); +} + +static void +load_thread (void *ti_) +{ + struct thread_info *ti = ti_; + int64_t sleep_time = 5 * TIMER_FREQ; + int64_t spin_time = sleep_time + 30 * TIMER_FREQ; + int64_t last_time = 0; + + thread_set_nice (ti->nice); + timer_sleep (sleep_time - timer_elapsed (ti->start_time)); + while (timer_elapsed (ti->start_time) < spin_time) + { + int64_t cur_time = timer_ticks (); + if (cur_time != last_time) + ti->tick_count++; + last_time = cur_time; + } +} |
