Add threads tests.
[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.
8
9    Based on a test originally submitted for Stanford's CS 140 in
10    winter 1999 by by Matt Franklin
11    <startled@leland.stanford.edu>, Greg Hutchins
12    <gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
13    Modified by arens and yph. */
14
15 /* If you've implemented thread_join(), you can uncomment this. */
16 /*#define THREAD_JOIN_IMPLEMENTED*/
17
18 /* Uncomment to print progress messages. */
19 /*#define SHOW_PROGRESS*/
20
21 #include "threads/test.h"
22 #include <stdio.h>
23 #include "threads/synch.h"
24 #include "threads/thread.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 const 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
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);
45       tids[i] = 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     {
51 #ifdef THREAD_JOIN_IMPLEMENTED
52       thread_join (tids[i]);
53 #else
54       sema_down (&done[i]);
55 #endif
56     }
57   printf ("Multilevel feedback queue scheduler test done.\n");
58 }
59
60 static void
61 cpu_thread (void *sema_) 
62 {
63   struct semaphore *sema = sema_;
64   int64_t start = timer_ticks ();
65   struct lock lock;
66   int i;
67
68   lock_init (&lock, "cpu");
69
70   for (i = 0; i < 5000; i++)
71     {
72       lock_acquire (&lock);
73 #ifdef SHOW_PROGRESS
74       printf ("CPU intensive: %d\n", thread_get_priority ());
75 #endif
76       lock_release (&lock);
77     }
78
79   printf ("CPU bound thread finished in %"PRI64d" ticks.\n",
80           timer_elapsed (start));
81   
82   sema_up (sema);
83 }
84
85 static void
86 io_thread (void *sema_) 
87 {
88   struct semaphore *sema = sema_;
89   int64_t start = timer_ticks ();
90   int i;
91
92   for (i = 0; i < 1000; i++) 
93     {
94       timer_sleep (10); 
95 #ifdef SHOW_PROGRESS
96       printf ("IO intensive: %d\n", thread_get_priority ());
97 #endif
98     }
99
100   printf ("IO bound thread finished in %"PRI64d" ticks.\n",
101           timer_elapsed (start));
102   
103   sema_up (sema);
104 }
105
106 static void
107 io_cpu_thread (void *sema_) 
108 {
109   struct semaphore *sema = sema_;
110   struct lock lock;
111   int64_t start = timer_ticks ();
112   int i;
113
114   lock_init (&lock, "io & cpu");
115
116   for (i = 0; i < 800; i++) 
117     {
118       int j;
119       
120       timer_sleep (10);
121
122       for (j = 0; j < 15; j++) 
123         {
124           lock_acquire (&lock);
125 #ifdef SHOW_PROGRESS
126           printf ("Alternating IO/CPU: %d\n", thread_get_priority ());
127 #endif
128           lock_release (&lock);
129         }
130     }
131
132   printf ("Alternating IO/CPU thread finished in %"PRI64d" ticks.\n",
133           timer_elapsed (start));
134   
135   sema_up (sema);
136 }