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