DysectAPI::DysectErrorCode Backend::handleTimerActions() { pthread_mutex_lock(&probesPendingActionMutex); if (probesPendingAction.size() > 0) { DYSECTVERBOSE(true, "Handle timer actions"); vector<Probe*>::iterator probeIter = probesPendingAction.begin(); for(;probeIter != probesPendingAction.end(); probeIter++) { Probe* probe = *probeIter; Domain* dom = probe->getDomain(); DYSECTVERBOSE(true, "Sending enqueued actions for timed probe: %x", dom->getId()); probe->sendEnqueuedActions(); if(probe->numWaitingProcs() > 0) { ProcessSet::ptr lprocset = probe->getWaitingProcs(); probe->enableChildren(lprocset); if(probe->getLifeSpan() == fireOnce) probe->disable(lprocset); lprocset->continueProcs(); probe->releaseWaitingProcs(); } } probesPendingAction.clear(); } pthread_mutex_unlock(&probesPendingActionMutex); return OK; }
DysectAPI::DysectErrorCode Backend::handleTimerEvents() { if(SafeTimer::anySyncReady()) { Err::verbose(true, "Handle timer events"); vector<Probe*> readyProbes = SafeTimer::getAndClearSyncReady(); vector<Probe*>::iterator probeIter = readyProbes.begin(); for(;probeIter != readyProbes.end(); probeIter++) { Probe* probe = *probeIter; Domain* dom = probe->getDomain(); Err::verbose(true, "Sending enqueued notifications for timed probe: %x", dom->getId()); probe->sendEnqueuedNotifications(); probe->sendEnqueuedActions(); } } return OK; }
DysectAPI::DysectErrorCode Backend::handleTimerEvents() { if(SafeTimer::anySyncReady()) { DYSECTVERBOSE(true, "Handle timer notifications"); vector<Probe*> readyProbes = SafeTimer::getAndClearSyncReady(); vector<Probe*>::iterator probeIter = readyProbes.begin(); for(;probeIter != readyProbes.end(); probeIter++) { Probe* probe = *probeIter; Domain* dom = probe->getDomain(); DYSECTVERBOSE(true, "Sending enqueued notifications for timed probe: %x", dom->getId()); probe->sendEnqueuedNotifications(); pthread_mutex_lock(&probesPendingActionMutex); probesPendingAction.push_back(probe); pthread_mutex_unlock(&probesPendingActionMutex); } } return OK; }
bool BucketAgg::collect(void* process, void *thread) { Process::const_ptr process_ptr = *(Process::const_ptr*)process; Thread::const_ptr thread_ptr = *(Thread::const_ptr*)thread; if(!process_ptr) { return DYSECTVERBOSE(false, "Process object not available"); return false; } // Get the rank of the process Probe *owner = getOwner(); if (!owner) { return DYSECTVERBOSE(false, "Could not find Probe owner"); } Domain *dom = owner->getDomain(); if (!dom) { return DYSECTVERBOSE(false, "Could not find Domain"); } std::map<int, Dyninst::ProcControlAPI::Process::ptr> *mpiRankToProcessMap; mpiRankToProcessMap = dom->getMpiRankToProcessMap(); if (!mpiRankToProcessMap) { return DYSECTVERBOSE(false, "Could not find MPI rank map"); } int rank = -1; std::map<int, Dyninst::ProcControlAPI::Process::ptr>::iterator iter; for (iter = mpiRankToProcessMap->begin(); iter != mpiRankToProcessMap->end(); iter++) { if (iter->second == process_ptr) { rank = iter->first; break; } } if (rank == -1) { return DYSECTVERBOSE(false, "Failed to determine Rank"); } // Read the value of the variable ProcDebug* pDebug; Walker* proc = (Walker*)process_ptr->getData(); if(!proc) { return DYSECTVERBOSE(false, "Could not get walker from process"); } bool wasRunning; if (process_ptr->allThreadsRunning()) { wasRunning = true; pDebug = dynamic_cast<ProcDebug *>(proc->getProcessState()); if (pDebug == NULL) { return DYSECTWARN(false, "Failed to dynamic_cast ProcDebug pointer"); } if (pDebug->isTerminated()) { return DYSECTWARN(false, "Process is terminated"); } if (pDebug->pause() == false) { return DYSECTWARN(false, "Failed to pause process"); } } DataRef ref(Value::floatType, variableName.c_str()); TargetVar var(variableName.c_str()); ConditionResult condRes; Value val; DysectErrorCode readStatus = var.getValue(condRes, val, process_ptr, thread_ptr->getTID()); if (wasRunning == true) { if (pDebug->resume() == false) { return DYSECTWARN(false, "Failed to resume process"); } } if (readStatus != OK) { return DYSECTWARN(false, "Could not read value from reference"); } if (condRes != Resolved) { return DYSECTINFO(false, "Value not available - could be optimized out!"); } if (variableType == Value::noType) { variableType = val.getType(); } int bucket = getBucketFromValue(val); buckets[bucket] += 1; string valStr; val.getStr(valStr); DYSECTVERBOSE(true, "Rank %d read the value %s and will place it in bucket %d", rank, valStr.c_str(), bucket); 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; }