9d66a6f991b695033476542c94279f4bd7412fe9
[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   tid_t tids[3];
37   int i;
38
39   printf ("\n"
40           "Testing multilevel feedback queue scheduler.\n");
41
42   /* Start threads. */
43   for (i = 0; i < 3; i++) 
44     {
45       sema_init (&done[i], 0, names[i]);
46       tids[i] = thread_create (names[i], PRI_DEFAULT, funcs[i], &done[i]);
47     }
48
49   /* Wait for threads to finish. */
50   for (i = 0; i < 3; i++)
51     {
52 #ifdef THREAD_JOIN_IMPLEMENTED
53       thread_join (tids[i]);
54 #else
55       sema_down (&done[i]);
56 #endif
57     }
58   printf ("Multilevel feedback queue scheduler test done.\n");
59 }
60
61 static void
62 cpu_thread (void *sema_) 
63 {
64   struct semaphore *sema = sema_;
65   int64_t start = timer_ticks ();
66   struct lock lock;
67   int i;
68
69   lock_init (&lock, "cpu");
70
71   for (i = 0; i < 5000; i++)
72     {
73       lock_acquire (&lock);
74 #ifdef SHOW_PROGRESS
75       printf ("CPU intensive: %d\n", thread_get_priority ());
76 #endif
77       lock_release (&lock);
78     }
79
80   printf ("CPU bound thread finished in %"PRId64" ticks.\n",
81           timer_elapsed (start));
82   
83   sema_up (sema);
84 }
85
86 static void
87 io_thread (void *sema_) 
88 {
89   struct semaphore *sema = sema_;
90   int64_t start = timer_ticks ();
91   int i;
92
93   for (i = 0; i < 1000; i++) 
94     {
95       timer_sleep (10); 
96 #ifdef SHOW_PROGRESS
97       printf ("IO intensive: %d\n", thread_get_priority ());
98 #endif
99     }
100
101   printf ("IO bound thread finished in %"PRId64" ticks.\n",
102           timer_elapsed (start));
103   
104   sema_up (sema);
105 }
106
107 static void
108 io_cpu_thread (void *sema_) 
109 {
110   struct semaphore *sema = sema_;
111   struct lock lock;
112   int64_t start = timer_ticks ();
113   int i;
114
115   lock_init (&lock, "io & cpu");
116
117   for (i = 0; i < 800; i++) 
118     {
119       int j;
120       
121       timer_sleep (10);
122
123       for (j = 0; j < 15; j++) 
124         {
125           lock_acquire (&lock);
126 #ifdef SHOW_PROGRESS
127           printf ("Alternating IO/CPU: %d\n", thread_get_priority ());
128 #endif
129           lock_release (&lock);
130         }
131     }
132
133   printf ("Alternating IO/CPU thread finished in %"PRId64" ticks.\n",
134           timer_elapsed (start));
135   
136   sema_up (sema);
137 }