1 /* Problem 1-1: Alarm Clock tests.
3 These tests will work with Pintos "out of the box" because an
4 implementation of timer_sleep() that "busy-waits" is
5 included. You need to replace that implementation with one
6 that doesn't busy-wait.
8 Based on a test originally submitted for Stanford's CS 140 in
9 winter 1998 by Rob Baesman <rbaesman@cs.stanford.edu>, Ben
10 Taskar <btaskar@cs.stanford.edu>, and Toli Kuznets
11 <tolik@cs.stanford.edu>. */
13 /* If you've implemented thread_join(), you can uncomment this. */
14 /*#define THREAD_JOIN_IMPLEMENTED*/
16 #include "threads/test.h"
18 #include "threads/synch.h"
19 #include "threads/thread.h"
20 #include "devices/timer.h"
22 static void test_sleep (int iterations);
31 struct sleep_thread_data
33 int64_t start; /* Start time. */
34 int duration; /* Number of ticks to sleep. */
35 int iterations; /* Number of iterations to run. */
36 int *product; /* Largest product so far. */
37 struct lock *lock; /* Lock on access to `product'. */
38 struct semaphore done; /* Completion semaphore. */
39 tid_t tid; /* Thread ID. */
42 static void sleeper (void *);
45 test_sleep (int iterations)
47 struct sleep_thread_data threads[5];
48 const int thread_cnt = sizeof threads / sizeof *threads;
55 "Testing %d sleeps per thread.\n"
56 "If successful, product of iteration count and\n"
57 "sleep duration will appear in nondescending order.\n",
60 /* Start all the threads. */
62 lock_init (&lock, "product");
63 start = timer_ticks ();
64 for (i = 0; i < thread_cnt; i++)
66 struct sleep_thread_data *t;
69 snprintf (name, sizeof name, "thread %d", i);
72 t->duration = (i + 1) * 10;
73 t->iterations = iterations;
74 t->product = &product;
76 sema_init (&t->done, 0, name);
77 t->tid = thread_create (name, PRI_DEFAULT, sleeper, t);
80 /* Wait for all the threads to finish. */
81 for (i = 0; i < thread_cnt; i++)
83 #ifdef THREAD_JOIN_IMPLEMENTED
84 thread_join (threads[i].tid);
86 sema_down (&threads[i].done);
96 struct sleep_thread_data *t = t_;
99 for (i = 1; i <= t->iterations; i++)
102 int new_product = i * t->duration;
104 timer_sleep ((t->start + new_product) - timer_ticks ());
106 lock_acquire (t->lock);
107 old_product = *t->product;
108 *t->product = new_product;
109 lock_release (t->lock);
111 printf ("%s: duration=%d, iteration=%d, product=%d\n",
112 thread_name (), t->duration, i, new_product);
114 if (old_product > new_product)
115 printf ("%s: Out of order sleep completion (%d > %d)!\n",
116 thread_name (), old_product, new_product);
119 /* Signal completion. */