diff options
Diffstat (limited to 'tests/threads/mlfqs-fair.c')
| -rw-r--r-- | tests/threads/mlfqs-fair.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/tests/threads/mlfqs-fair.c b/tests/threads/mlfqs-fair.c new file mode 100644 index 0000000..3b1bea5 --- /dev/null +++ b/tests/threads/mlfqs-fair.c | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* Measures the correctness of the "nice" implementation. | ||
| 2 | |||
| 3 | The "fair" tests run either 2 or 20 threads all niced to 0. | ||
| 4 | The threads should all receive approximately the same number | ||
| 5 | of ticks. Each test runs for 30 seconds, so the ticks should | ||
| 6 | also sum to approximately 30 * 100 == 3000 ticks. | ||
| 7 | |||
| 8 | The mlfqs-nice-2 test runs 2 threads, one with nice 0, the | ||
| 9 | other with nice 5, which should receive 1,904 and 1,096 ticks, | ||
| 10 | respectively, over 30 seconds. | ||
| 11 | |||
| 12 | The mlfqs-nice-10 test runs 10 threads with nice 0 through 9. | ||
| 13 | They should receive 672, 588, 492, 408, 316, 232, 152, 92, 40, | ||
| 14 | and 8 ticks, respectively, over 30 seconds. | ||
| 15 | |||
| 16 | (The above are computed via simulation in mlfqs.pm.) */ | ||
| 17 | |||
| 18 | #include <stdio.h> | ||
| 19 | #include <inttypes.h> | ||
| 20 | #include "tests/threads/tests.h" | ||
| 21 | #include "threads/init.h" | ||
| 22 | #include "threads/malloc.h" | ||
| 23 | #include "threads/palloc.h" | ||
| 24 | #include "threads/synch.h" | ||
| 25 | #include "threads/thread.h" | ||
| 26 | #include "devices/timer.h" | ||
| 27 | |||
| 28 | static void test_mlfqs_fair (int thread_cnt, int nice_min, int nice_step); | ||
| 29 | |||
| 30 | void | ||
| 31 | test_mlfqs_fair_2 (void) | ||
| 32 | { | ||
| 33 | test_mlfqs_fair (2, 0, 0); | ||
| 34 | } | ||
| 35 | |||
| 36 | void | ||
| 37 | test_mlfqs_fair_20 (void) | ||
| 38 | { | ||
| 39 | test_mlfqs_fair (20, 0, 0); | ||
| 40 | } | ||
| 41 | |||
| 42 | void | ||
| 43 | test_mlfqs_nice_2 (void) | ||
| 44 | { | ||
| 45 | test_mlfqs_fair (2, 0, 5); | ||
| 46 | } | ||
| 47 | |||
| 48 | void | ||
| 49 | test_mlfqs_nice_10 (void) | ||
| 50 | { | ||
| 51 | test_mlfqs_fair (10, 0, 1); | ||
| 52 | } | ||
| 53 | |||
| 54 | #define MAX_THREAD_CNT 20 | ||
| 55 | |||
| 56 | struct thread_info | ||
| 57 | { | ||
| 58 | int64_t start_time; | ||
| 59 | int tick_count; | ||
| 60 | int nice; | ||
| 61 | }; | ||
| 62 | |||
| 63 | static void load_thread (void *aux); | ||
| 64 | |||
| 65 | static void | ||
| 66 | test_mlfqs_fair (int thread_cnt, int nice_min, int nice_step) | ||
| 67 | { | ||
| 68 | struct thread_info info[MAX_THREAD_CNT]; | ||
| 69 | int64_t start_time; | ||
| 70 | int nice; | ||
| 71 | int i; | ||
| 72 | |||
| 73 | ASSERT (thread_mlfqs); | ||
| 74 | ASSERT (thread_cnt <= MAX_THREAD_CNT); | ||
| 75 | ASSERT (nice_min >= -10); | ||
| 76 | ASSERT (nice_step >= 0); | ||
| 77 | ASSERT (nice_min + nice_step * (thread_cnt - 1) <= 20); | ||
| 78 | |||
| 79 | thread_set_nice (-20); | ||
| 80 | |||
| 81 | start_time = timer_ticks (); | ||
| 82 | msg ("Starting %d threads...", thread_cnt); | ||
| 83 | nice = nice_min; | ||
| 84 | for (i = 0; i < thread_cnt; i++) | ||
| 85 | { | ||
| 86 | struct thread_info *ti = &info[i]; | ||
| 87 | char name[16]; | ||
| 88 | |||
| 89 | ti->start_time = start_time; | ||
| 90 | ti->tick_count = 0; | ||
| 91 | ti->nice = nice; | ||
| 92 | |||
| 93 | snprintf(name, sizeof name, "load %d", i); | ||
| 94 | thread_create (name, PRI_DEFAULT, load_thread, ti); | ||
| 95 | |||
| 96 | nice += nice_step; | ||
| 97 | } | ||
| 98 | msg ("Starting threads took %"PRId64" ticks.", timer_elapsed (start_time)); | ||
| 99 | |||
| 100 | msg ("Sleeping 40 seconds to let threads run, please wait..."); | ||
| 101 | timer_sleep (40 * TIMER_FREQ); | ||
| 102 | |||
| 103 | for (i = 0; i < thread_cnt; i++) | ||
| 104 | msg ("Thread %d received %d ticks.", i, info[i].tick_count); | ||
| 105 | } | ||
| 106 | |||
| 107 | static void | ||
| 108 | load_thread (void *ti_) | ||
| 109 | { | ||
| 110 | struct thread_info *ti = ti_; | ||
| 111 | int64_t sleep_time = 5 * TIMER_FREQ; | ||
| 112 | int64_t spin_time = sleep_time + 30 * TIMER_FREQ; | ||
| 113 | int64_t last_time = 0; | ||
| 114 | |||
| 115 | thread_set_nice (ti->nice); | ||
| 116 | timer_sleep (sleep_time - timer_elapsed (ti->start_time)); | ||
| 117 | while (timer_elapsed (ti->start_time) < spin_time) | ||
| 118 | { | ||
| 119 | int64_t cur_time = timer_ticks (); | ||
| 120 | if (cur_time != last_time) | ||
| 121 | ti->tick_count++; | ||
| 122 | last_time = cur_time; | ||
| 123 | } | ||
| 124 | } | ||
