1 /* Problem 1-1: Alarm Clock tests.
3 Based on a test originally submitted for Stanford's CS 140 in
4 winter 1998 by Rob Baesman <rbaesman@cs.stanford.edu>, Ben
5 Taskar <btaskar@cs.stanford.edu>, and Toli Kuznets
6 <tolik@cs.stanford.edu>. */
8 #include "threads/test.h"
10 #include "threads/malloc.h"
11 #include "threads/synch.h"
12 #include "threads/thread.h"
13 #include "devices/timer.h"
15 /* Number of iterations. */
16 #define ITERATION_CNT 1
18 static void test_sleep (int iterations);
23 test_sleep (ITERATION_CNT);
26 struct sleep_thread_data
28 int64_t start; /* Start time. */
29 int duration; /* Number of ticks to sleep. */
30 int iterations; /* Number of iterations to run. */
31 struct semaphore done; /* Completion semaphore. */
32 tid_t tid; /* Thread ID. */
34 struct lock *lock; /* Lock on access to remaining members. */
35 int *product; /* Largest product so far. */
36 char **out; /* Output pointer. */
39 static void sleeper (void *);
42 test_sleep (int iterations)
44 struct sleep_thread_data threads[5];
45 const int thread_cnt = sizeof threads / sizeof *threads;
53 "Testing %d sleeps per thread.\n"
54 "If successful, product of iteration count and\n"
55 "sleep duration will appear in nondescending order.\n",
58 /* Start all the threads. */
60 lock_init (&lock, "product");
61 cp = output = malloc (128 * iterations * thread_cnt);
62 ASSERT (output != NULL);
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 sema_init (&t->done, 0, name);
75 t->tid = thread_create (name, PRI_DEFAULT, sleeper, t);
78 t->product = &product;
82 /* Wait for all the threads to finish. */
83 for (i = 0; i < thread_cnt; i++)
84 sema_down (&threads[i].done);
86 printf ("%s...done\n", output);
92 struct sleep_thread_data *t = t_;
95 for (i = 1; i <= t->iterations; i++)
98 int new_product = i * t->duration;
100 timer_sleep ((t->start + new_product) - timer_ticks ());
102 lock_acquire (t->lock);
103 old_product = *t->product;
104 *t->product = new_product;
105 *t->out += snprintf (*t->out, 128,
106 "%s: duration=%d, iteration=%d, product=%d\n",
107 thread_name (), t->duration, i, new_product);
108 if (old_product > new_product)
109 *t->out += snprintf (*t->out, 128,
110 "%s: Out of order sleep completion (%d > %d)!\n",
111 thread_name (), old_product, new_product);
112 lock_release (t->lock);
115 /* Signal completion. */