+ /* Wait long enough for all the threads to finish. */
+ timer_sleep (100 + thread_cnt * iterations * 10 + 100);
+ printf ("done\n\n");
+
+ /* Acquire the output lock in case some rogue thread is still
+ running. */
+ lock_acquire (&test.output_lock);
+
+ /* Print completion order. */
+ product = 0;
+ for (op = output; op < test.output_pos; op++)
+ {
+ struct sleep_thread *t;
+ int new_prod;
+
+ ASSERT (*op >= 0 && *op < thread_cnt);
+ t = threads + *op;
+
+ new_prod = ++t->iterations * t->duration;
+
+ printf ("thread %d: duration=%d, iteration=%d, product=%d\n",
+ t->id, t->duration, t->iterations, new_prod);
+
+ if (new_prod >= product)
+ product = new_prod;
+ else
+ printf ("FAIL: thread %d woke up out of order (%d > %d)!\n",
+ t->id, product, new_prod);
+ }
+
+ /* Verify that we had the proper number of wakeups. */
+ for (i = 0; i < thread_cnt; i++)
+ if (threads[i].iterations != iterations)
+ printf ("FAIL: thread %d woke up %d times instead of %d\n",
+ i, threads[i].iterations, iterations);