/** * Start the race. */ void RelayRace::run(void) { trace::Call *call; call = parser.parse_call(); if (!call) { /* Nothing to do */ return; } /* If the user wants to loop we need to get a bookmark target. We * usually get this after replaying a call that ends a frame, but * for a trace that has only one frame we need to get it at the * beginning. */ if (loopOnFinish) { parser.getBookmark(lastFrameStart); } 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(); }
/** * 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(); } } }
/** * 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(); }
/** * 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(); }
/** * 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); }