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"
16 #error This test not applicable with MLFQS enabled.
19 static void test_sleep (int iterations);
27 struct sleep_thread_data
29 int64_t start; /* Start time. */
30 int duration; /* Number of ticks to sleep. */
31 int iterations; /* Number of iterations to run. */
32 struct semaphore done; /* Completion semaphore. */
33 tid_t tid; /* Thread ID. */
34 int id; /* Sleeper ID. */
36 struct lock *lock; /* Lock on access to `op'. */
37 int **op; /* Output buffer position. */
40 static void sleeper (void *);
43 test_sleep (int iterations)
45 struct sleep_thread_data threads[5];
46 const int thread_cnt = sizeof threads / sizeof *threads;
54 "Testing %d sleeps per thread.\n"
55 "If successful, product of iteration count and\n"
56 "sleep duration will appear in nondescending order.\n",
59 /* Start all the threads. */
61 lock_init (&lock, "product");
62 op = output = malloc (sizeof *output * iterations * thread_cnt * 2);
63 ASSERT (output != NULL);
64 start = timer_ticks ();
65 for (i = 0; i < thread_cnt; i++)
67 struct sleep_thread_data *t;
70 snprintf (name, sizeof name, "thread %d", i);
73 t->duration = (i + 1) * 10;
74 t->iterations = iterations;
75 sema_init (&t->done, 0, name);
76 t->tid = thread_create (name, PRI_DEFAULT, sleeper, t);
83 /* Wait for all the threads to finish. */
84 for (i = 0; i < thread_cnt; i++)
86 sema_down (&threads[i].done);
87 threads[i].iterations = 1;
90 /* Print output buffer. */
92 for (; output < op; output++)
94 struct sleep_thread_data *t;
97 ASSERT (*output >= 0 && *output < thread_cnt);
98 t = threads + *output;
100 new_prod = t->iterations++ * t->duration;
102 printf ("thread %d: duration=%d, iteration=%d, product=%d\n",
103 t->id, t->duration, t->iterations, new_prod);
105 if (new_prod >= product)
108 printf ("thread %d: Out of order sleep completion (%d > %d)!\n",
109 t->id, product, new_prod);
112 printf ("...done\n");
118 struct sleep_thread_data *t = t_;
121 for (i = 1; i <= t->iterations; i++)
123 timer_sleep ((t->start + i * t->duration) - timer_ticks ());
125 lock_acquire (t->lock);
127 lock_release (t->lock);
130 /* Signal completion. */