+ RelayRunner *foreRunner = getForeRunner();
+ if (call->thread_id == 0) {
+ /* We are the forerunner thread, so no need to pass baton */
+ foreRunner->baton = call;
+ } else {
+ passBaton(call);
+ }
+
+ /* Start the forerunner thread */
+ foreRunner->runRace();
+}
+
+
+/**
+ * Pass the baton (i.e., the call) to the appropriate thread.
+ */
+void
+RelayRace::passBaton(trace::Call *call) {
+ if (0) std::cerr << "switching to thread " << call->thread_id << "\n";
+ RelayRunner *runner = getRunner(call->thread_id);
+ runner->receiveBaton(call);
+}
+
+
+/**
+ * Called when a runner other than the forerunner reaches the finish line.
+ *
+ * Only the fore runner can finish the race, so inform him that the race is
+ * finished.
+ */
+void
+RelayRace::finishLine(void) {
+ RelayRunner *foreRunner = getForeRunner();
+ foreRunner->finishRace();
+}
+
+
+/**
+ * Called by the fore runner after finish line to stop all other runners.
+ */
+void
+RelayRace::stopRunners(void) {
+ std::vector<RelayRunner*>::const_iterator it;
+ for (it = runners.begin() + 1; it != runners.end(); ++it) {
+ RelayRunner* runner = *it;
+ if (runner) {
+ runner->finishRace();
+ }
+ }