bool SafeTimer::startSyncTimer(Probe* probe) { if(!probe) return false; if(syncTimerRunning(probe)) { return true; } Domain* dom = probe->getDomain(); if(!dom) return false; long timeout = dom->getWaitTime(); long expectedTimeout = getTimeStamp() + timeout; if(expectedTimeout <= nextTimeout) { nextTimeout = expectedTimeout; } waitingProbes.insert(probe); probesTimeoutMap.insert(pair<long, Probe*>(expectedTimeout, probe)); return true; }
Process::cb_ret_t Backend::handleEvent(Dyninst::ProcControlAPI::Process::const_ptr curProcess, Dyninst::ProcControlAPI::Thread::const_ptr curThread, DysectAPI::Event* dysectEvent) { Process::cb_ret_t retState = Process::cbDefault; // Let event know that it was triggered. // Used for event composition Walker* proc = (Walker*)curProcess->getData(); if(!proc) { Err::warn(true, "Missing payload in process object: could not get walker"); } else { dysectEvent->triggered(curProcess, curThread); // Find owning probe Probe* probe = dysectEvent->getOwner(); if(!probe) { Err::warn(true, "Probe could not be found for event object"); } else { // If enqueued disabled - stop and await //if(probe->isDisabled(curProcess)) { // probe->addWaitingProc(curProcess); // return Process::cbProcStop; // //return Process::cbDefault; //} // Composed events might require several events being triggered if(probe->wasTriggered(curProcess, curThread)) { // Required events indeed triggered // Evaluate conditions ConditionResult result; Err::verbose(true, "Evaluate condition!"); if(probe->evaluateConditions(result, curProcess, curThread) == DysectAPI::OK) { if(result == ResolvedTrue) { Err::verbose(true, "Condition satisfied"); Domain* dom = probe->getDomain(); assert(dom != 0); if(dom->getWaitTime() == Wait::inf) { // Block strictly, until all processes have shown up Err::verbose(true, "Enqueuing notification for static domain"); probe->enqueueNotifyPacket(); probe->enqueueAction(curProcess, curThread); } else if(dom->getWaitTime() != Wait::NoWait) { if(!DysectAPI::SafeTimer::syncTimerRunning(probe)) { Err::verbose(true, "Start timer and enqueue: %x", dom->getId()); DysectAPI::SafeTimer::startSyncTimer(probe); } else { Err::verbose(true, "Timer already running - just enqueue"); } if(probe->doNotify()) { probe->enqueueNotifyPacket(); } probe->enqueueAction(curProcess, curThread); } else { // No-wait probe if(probe->doNotify()) { probe->notifyTriggered(); } probe->triggerAction(curProcess, curThread); } if(probe->waitForOthers()) { Err::verbose(true, "Wait for group members"); probe->addWaitingProc(curProcess); if((dom->getWaitTime() == Wait::inf) && (probe->staticGroupWaiting())) { Err::verbose(true, "Sending enqueued notifications"); if(probe->doNotify()) { probe->sendEnqueuedNotifications(); } probe->sendEnqueuedActions(); } retState = Process::cbThreadStop; } else { Err::verbose(true, "Enable children for probe %x", dom->getId()); probe->enqueueEnable(curProcess); //Err::verbose(true, "Stopping thread in process %d", curProcess->getPid()); probe->addWaitingProc(curProcess); //retState = Process::cbThreadStop; retState = Process::cbProcStop; } if(probe->getLifeSpan() == fireOnce) { Err::verbose(true, "Requesting disablement of probe"); probe->enqueueDisable(curProcess); //Err::verbose(true, "Stopping thread in process %d", curProcess->getPid()); probe->addWaitingProc(curProcess); //retState = Process::cbThreadStop; retState = Process::cbProcStop; } #if 0 } else if(result == CollectiveResolvable) { // Block process and await resolution of collective operations //probe->addWaitingCond(curProcess, curThread); Err::warn(false, "Condition stalls not yet supported"); Err::verbose(true, "Stopping thread in process %d", curProcess->getPid()); retState = Process::cbProcStop; //retState = Process::cbThreadStop; #endif } else if(result == ResolvedFalse) { if(probe->getLifeSpan() == fireOnce) { Err::verbose(true, "Requesting disablement of probe"); // Get out of the way probe->enqueueDisable(curProcess); retState = Process::cbProcStop; } else { retState = Process::cbProcContinue; //probe->addWaitingProc(curProcess); } // probe->addWaitingProc(curProcess); } } else { Err::warn(false, "Could not evaluate conditions for probe"); } } } } return retState; }