+ }
+}
+
+
+/**
+ * Get (or instantiate) a runner for the specified leg.
+ */
+RelayRunner *
+RelayRace::getRunner(unsigned leg) {
+ RelayRunner *runner;
+
+ if (leg >= runners.size()) {
+ runners.resize(leg + 1);
+ runner = 0;
+ } else {
+ runner = runners[leg];
+ }
+ if (!runner) {
+ runner = new RelayRunner(this, leg);
+ runners[leg] = runner;
+ }
+ return runner;
+}
+
+
+/**
+ * Start the race.
+ */
+void
+RelayRace::run(void) {
+ trace::Call *call;
+ call = parser.parse_call();
+ if (!call) {
+ /* Nothing to do */
+ return;
+ }
+
+ 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();
+}