1f97b2e7edb6fb9ed008a2811d111f638499c9e6
[pintos-anon] / src / tests / threads / p1-4.c
1 /* Problem 1-4: Advanced Scheduler tests.
2
3    This depends on a correctly working Alarm Clock (Problem 1-1).
4
5    Run this test with and without the MLFQS enabled.  The
6    threads' reported test should be better with MLFQS on than
7    with it off.  You may have to tune the loop counts to get
8    reasonable numbers.
9
10    Based on a test originally submitted for Stanford's CS 140 in
11    winter 1999 by by Matt Franklin
12    <startled@leland.stanford.edu>, Greg Hutchins
13    <gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
14    Modified by arens and yph. */
15
16 /* Uncomment to print progress messages. */
17 /*#define SHOW_PROGRESS*/
18
19 #include "threads/test.h"
20 #include <stdio.h>
21 #include <inttypes.h>
22 #include "threads/synch.h"
23 #include "threads/thread.h"
24 #include "devices/timer.h"
25
26 static thread_func io_thread;
27 static thread_func cpu_thread;
28 static thread_func io_cpu_thread;
29
30 void
31 test (void) 
32 {
33   static thread_func *funcs[] = {io_thread, cpu_thread, io_cpu_thread};
34   static const char *names[] = {"IO", "CPU", "IO & CPU"};
35   struct semaphore done[3];
36   int i;
37
38   printf ("\n"
39           "Testing multilevel feedback queue scheduler.\n");
40
41   /* Start threads. */
42   for (i = 0; i < 3; i++) 
43     {
44       sema_init (&done[i], 0, names[i]);
45       thread_create (names[i], PRI_DEFAULT, funcs[i], &done[i]);
46     }
47
48   /* Wait for threads to finish. */
49   for (i = 0; i < 3; i++)
50     sema_down (&done[i]);
51   printf ("Multilevel feedback queue scheduler test done.\n");
52 }
53
54 static void
55 cpu_thread (void *sema_) 
56 {
57   struct semaphore *sema = sema_;
58   int64_t start = timer_ticks ();
59   struct lock lock;
60   int i;
61
62   lock_init (&lock, "cpu");
63
64   for (i = 0; i < 5000; i++)
65     {
66       lock_acquire (&lock);
67 #ifdef SHOW_PROGRESS
68       printf ("CPU intensive: %d\n", thread_get_priority ());
69 #endif
70       lock_release (&lock);
71     }
72
73   printf ("CPU bound thread finished in %"PRId64" ticks.\n",
74           timer_elapsed (start));
75   
76   sema_up (sema);
77 }
78
79 static void
80 io_thread (void *sema_) 
81 {
82   struct semaphore *sema = sema_;
83   int64_t start = timer_ticks ();
84   int i;
85
86   for (i = 0; i < 1000; i++) 
87     {
88       timer_sleep (10); 
89 #ifdef SHOW_PROGRESS
90       printf ("IO intensive: %d\n", thread_get_priority ());
91 #endif
92     }
93
94   printf ("IO bound thread finished in %"PRId64" ticks.\n",
95           timer_elapsed (start));
96   
97   sema_up (sema);
98 }
99
100 static void
101 io_cpu_thread (void *sema_) 
102 {
103   struct semaphore *sema = sema_;
104   struct lock lock;
105   int64_t start = timer_ticks ();
106   int i;
107
108   lock_init (&lock, "io & cpu");
109
110   for (i = 0; i < 800; i++) 
111     {
112       int j;
113       
114       timer_sleep (10);
115
116       for (j = 0; j < 15; j++) 
117         {
118           lock_acquire (&lock);
119 #ifdef SHOW_PROGRESS
120           printf ("Alternating IO/CPU: %d\n", thread_get_priority ());
121 #endif
122           lock_release (&lock);
123         }
124     }
125
126   printf ("Alternating IO/CPU thread finished in %"PRId64" ticks.\n",
127           timer_elapsed (start));
128   
129   sema_up (sema);
130 }