summaryrefslogtreecommitdiffstats
path: root/tests/threads/mlfqs-fair.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/threads/mlfqs-fair.c')
-rw-r--r--tests/threads/mlfqs-fair.c124
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
28static void test_mlfqs_fair (int thread_cnt, int nice_min, int nice_step);
29
30void
31test_mlfqs_fair_2 (void)
32{
33 test_mlfqs_fair (2, 0, 0);
34}
35
36void
37test_mlfqs_fair_20 (void)
38{
39 test_mlfqs_fair (20, 0, 0);
40}
41
42void
43test_mlfqs_nice_2 (void)
44{
45 test_mlfqs_fair (2, 0, 5);
46}
47
48void
49test_mlfqs_nice_10 (void)
50{
51 test_mlfqs_fair (10, 0, 1);
52}
53
54#define MAX_THREAD_CNT 20
55
56struct thread_info
57 {
58 int64_t start_time;
59 int tick_count;
60 int nice;
61 };
62
63static void load_thread (void *aux);
64
65static void
66test_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
107static void
108load_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}