CS318 - Pintos
Pintos source browser for JHU CS318 course
mlfqs-fair.c
Go to the documentation of this file.
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
32 {
33  test_mlfqs_fair (2, 0, 0);
34 }
35 
36 void
38 {
39  test_mlfqs_fair (20, 0, 0);
40 }
41 
42 void
44 {
45  test_mlfqs_fair (2, 0, 5);
46 }
47 
48 void
50 {
51  test_mlfqs_fair (10, 0, 1);
52 }
53 
54 #define MAX_THREAD_CNT 20
55 
56 struct thread_info
57  {
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];
70  int nice;
71  int i;
72 
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 
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);
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 }
load_thread
static void load_thread(void *aux)
Definition: mlfqs-fair.c:108
name
char * name[]
Definition: insult.c:47
TIMER_FREQ
#define TIMER_FREQ
Number of timer interrupts per second.
Definition: timer.h:8
snprintf
int snprintf(char *buffer, size_t buf_size, const char *format,...)
Like printf(), except that output is stored into BUFFER, which must have space for BUF_SIZE character...
Definition: stdio.c:62
test_mlfqs_fair
static void test_mlfqs_fair(int thread_cnt, int nice_min, int nice_step)
Measures the correctness of the "nice" implementation.
Definition: mlfqs-fair.c:66
thread_info::nice
int nice
Definition: mlfqs-fair.c:60
test_mlfqs_nice_10
void test_mlfqs_nice_10(void)
Definition: mlfqs-fair.c:49
timer_elapsed
int64_t timer_elapsed(int64_t then)
Returns the number of timer ticks elapsed since THEN, which should be a value once returned by timer_...
Definition: timer.c:82
test_mlfqs_fair_20
void test_mlfqs_fair_20(void)
Definition: mlfqs-fair.c:37
thread_info::start_time
int64_t start_time
Definition: mlfqs-fair.c:58
PRId64
#define PRId64
Definition: inttypes.h:27
start_time
static int64_t start_time
Starts 60 threads that each sleep for 10 seconds, then spin in a tight loop for 60 seconds,...
Definition: mlfqs-load-60.c:108
thread_info::tick_count
int tick_count
Definition: mlfqs-fair.c:59
int64_t
signed long long int int64_t
Definition: stdint.h:16
test_mlfqs_nice_2
void test_mlfqs_nice_2(void)
Definition: mlfqs-fair.c:43
init.h
timer.h
timer_sleep
void timer_sleep(int64_t ticks)
Sleeps for approximately TICKS timer ticks.
Definition: timer.c:90
test_mlfqs_fair_2
void test_mlfqs_fair_2(void)
Definition: mlfqs-fair.c:31
malloc.h
palloc.h
timer_ticks
int64_t timer_ticks(void)
Returns the number of timer ticks since the OS booted.
Definition: timer.c:71
ASSERT
#define ASSERT(CONDITION)
This is outside the header guard so that debug.h may be included multiple times with different settin...
Definition: debug.h:31
msg
void msg(const char *format,...)
Definition: lib.c:28
thread_mlfqs
bool thread_mlfqs
If false (default), use round-robin scheduler.
Definition: thread.c:60
thread_create
tid_t thread_create(const char *name, int priority, thread_func *function, void *aux)
Creates a new kernel thread named NAME with the given initial PRIORITY, which executes FUNCTION passi...
Definition: thread.c:166
tests.h
thread_info
Definition: mlfqs-fair.c:56
MAX_THREAD_CNT
#define MAX_THREAD_CNT
Definition: mlfqs-fair.c:54
thread.h
synch.h
inttypes.h
thread_set_nice
void thread_set_nice(int nice UNUSED)
Sets the current thread's nice value to NICE.
Definition: thread.c:350
PRI_DEFAULT
#define PRI_DEFAULT
Default priority.
Definition: thread.h:24