void GenProbeSequenceTemplate (ProbeSequence &seq, unsigned M, unsigned T) { ProbeSequence scores; GenExpectScores(scores, M); assert(T > 0); std::priority_queue<Probe, std::vector<Probe>, ProbeGT> heap; Probe init; init.mask = init.shift = 0; init.score = 0; init.reserve = 0; heap.push(init); seq.clear(); for (;;) { if (heap.empty()) break; seq.push_back(heap.top()); if (seq.size() == T) break; Probe shift = heap.top(); heap.pop(); for (unsigned next = shift.reserve; next < 2 * M; ++next) { if (!shift.conflict(scores[next])) { Probe tmp = shift + scores[next]; tmp.reserve = next + 1; heap.push(tmp); } } } }
int ClassAdAssign(ClassAd & ad, const char * pattr, const Probe& probe) { MyString attr; attr.sprintf("%sCount", pattr); ad.Assign(attr.Value(), probe.Count); attr.sprintf("%sSum", pattr); int ret = ad.Assign(attr.Value(), probe.Sum); if (probe.Count > 0) { attr.sprintf("%sAvg", pattr); ad.Assign(attr.Value(), probe.Avg()); attr.sprintf("%sMin", pattr); ad.Assign(attr.Value(), probe.Min); attr.sprintf("%sMax", pattr); ad.Assign(attr.Value(), probe.Max); attr.sprintf("%sStd", pattr); ad.Assign(attr.Value(), probe.Std()); } return ret; }
// maak probes int Circuit::CreateProbes(std::vector<std::string> Probes) { pView->Print("Create probes!"); try { for (int i = 0; i < Probes.size(); i++) { // maak een probe Probe *pProbe = (Probe *)Factory::instance()->RequestComponent(_PROBE); if (pProbe != nullptr) { // zet de probe id. pProbe->SetId(Probes.at(i).substr(0, Probes.at(i).find(":"))); this->Probes.push_back(pProbe); } else throw 1; } } catch (int e) { // probe error return ErrorFound("Error in creating probes!"); } return 1; }
DysectAPI::DysectErrorCode Backend::relayPacket(PacketPtr* packet, int tag, Stream* stream) { if(tag == DysectGlobalReadyTag){ // Stream to respond when all streams have been bound if(controlStream != 0) { return DYSECTWARN(Error, "Control stream already set"); } controlStream = stream; if((state == ready) && (!streamBindAckSent)) { ackBindings(); } return OK; } switch(state) { case bindingStreams: { if(Domain::isInitTag(tag)) { if(bindStream(tag, stream) != OK) { return DYSECTWARN(StreamError, "Failed to bind stream!"); } } else { assert(!"Save packet until all streams have been bound to domains - not yet supported"); } } break; case ready: { if(tag == DysectGlobalStartTag) { enableProbeRoots(); } else { if(Domain::isContinueTag(tag)) { Domain* dom = 0; if(!Domain::getDomainFromTag(dom, tag)) { DYSECTWARN(false, "Domain for tag %x could not be found", tag); } else { Probe* probe = dom->owner; if(!probe) { DYSECTWARN(false, "Probe for tag %x could not be found", tag); } else { DYSECTVERBOSE(true, "Handling packet for probe %x", probe->getId()); } } } } } break; default: return InvalidSystemState; break; } return OK; }
std::vector<double> Probes::get_probes_component_and_snapshot(std::size_t comp, std::size_t i) { std::vector<double> vals; for (std::size_t j = 0; j < local_size(); j++) { Probe* probe = (Probe*) _allprobes[j].second; vals.push_back(probe->get_probe_component_and_snapshot(comp, i)); } return vals; }
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 Frontend::broadcastStreamInits() { vector<Probe*>& roots = ProbeTree::getRoots(); long numRoots = roots.size(); for(int i = 0; i < numRoots; i++) { Probe* probe = roots[i]; probe->broadcastStreamInit(recursive); } return OK; }
DysectAPI::DysectErrorCode Probe::enableChildren(ProcessSet::ptr procset) { if(linked.empty()) { return OK; } vector<Probe*>::iterator probeIter = linked.begin(); for(;probeIter != linked.end(); probeIter++) { Probe* probe = *probeIter; probe->enable(procset); } return OK; }
void Probes::set_probes_from_ids(const Array<double>& u) { assert(u.size() == local_size() * value_size()); Array<double> _u(value_size()); for (std::size_t i = 0; i < local_size(); i++) { Probe* probe = (Probe*) _allprobes[i].second; for (std::size_t j=0; j<value_size(); j++) _u[j] = u[i*value_size() + j]; probe->restart_probe(_u); } }
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; }
// Single entry for debug daemon DysectStatus DysectAPI::onProcStart() { /* Probe creation */ Probe* foo = new Probe(Code::location("foo"), Domain::world(1000), Act::stat(AllProcs)); Probe* square = new Probe(Code::location("square<int>"), Domain::inherit(2000), Act::trace("At square")); /* Event chain */ foo->link(square); /* Setup probe tree */ ProbeTree::addRoot(foo); return DysectOK; }
DysectAPI::DysectErrorCode Backend::enableProbeRoots() { if(Backend::pauseApplication() != OK) { return Err::warn(Error, "Could not pause application!"); } vector<Probe*> roots = ProbeTree::getRoots(); for(int i = 0; i < roots.size(); i++) { Probe* probe = roots[i]; probe->enable(); } if(Backend::resumeApplication() != OK) { return Err::warn(Error, "Could not pause application!"); } return OK; }
DysectAPI::DysectErrorCode Backend::enableProbeRoots() { pthread_mutex_init(&probesPendingActionMutex, NULL); if(Backend::pauseApplication() != OK) { return DYSECTWARN(Error, "Could not pause application!"); } vector<Probe*> roots = ProbeTree::getRoots(); for(int i = 0; i < roots.size(); i++) { Probe* probe = roots[i]; probe->enable(); } if(Backend::resumeApplication() != OK) { return DYSECTWARN(Error, "Could not pause application!"); } 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; }
void dump_results(google::dense_hash_map<std::string, Probe*> &h_probes) { int cs1[5], cs2[5]; Probe *op; // Original probe google::dense_hash_map<std::string, Probe *>::iterator p_iter; for (p_iter=h_probes.begin(); p_iter!=h_probes.end(); p_iter++) { // In op we want always the original probe, not the rc one op = p_iter->second->is_a_rc_probe ? p_iter->second->rc : p_iter->second; if (!op->visited && (op->has_hits() || op->rc->has_hits())) { op->get_counters(cs1); op->rc->get_counters(cs2); std::cout << op->get_chrm() << "," << op->get_coordinates() << "," << op->get_id() << "," << op->get_ref() << "," << op->get_var() << "," << cs1[0] << "," << cs1[1] << "," << cs1[2] << "," << cs1[3] << "," << cs1[4] << "," << cs2[0] << "," << cs2[1] << "," << cs2[2] << "," << cs2[3] << "," << cs2[4] << "," << cs1[0] + cs2[0] << "," << cs1[1] + cs2[1] << "," << cs1[2] + cs2[2] << "," << cs1[3] + cs2[3] << "," << cs1[4] + cs2[4] << std::endl; op->visited = 1; op->rc->visited = 1; } } }
DysectAPI::DysectErrorCode Frontend::createStreams(struct DysectFEContext_t* context) { if(!context) { return Err::warn(Error, "Context not set"); } statFE = context->statFE; vector<Probe*>& roots = ProbeTree::getRoots(); long numRoots = roots.size(); // Populate domain with MRNet network and debug process tables Domain::setFEContext(context); // Prepare streams for(int i = 0; i < numRoots; i++) { Probe* probe = roots[i]; probe->prepareStream(recursive); } // Create streams for(int i = 0; i < numRoots; i++) { Probe* probe = roots[i]; probe->createStream(recursive); } if(Domain::createFdSet() != OK) { return Error; } for(int i = 0; i < numRoots; i++) { Probe* probe = roots[i]; if(probe->prepareAction(recursive) != OK) { Err::warn(Error, "Error occured while preparing actions"); } } 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; }
bool Probe::processRequests() { if(requestQueue.empty()) { return true; } pthread_mutex_lock(&requestQueueMutex); vector<ProbeRequest*> queue = requestQueue; requestQueue.clear(); pthread_mutex_unlock(&requestQueueMutex); ProcessSet::ptr continueSet = ProcessSet::newProcessSet(); // Sort queue deque<ProbeRequest*> sortedQueue; vector<ProbeRequest*>::iterator requestIter = queue.begin(); for(int i = 0; requestIter != queue.end(); requestIter++) { ProbeRequest* request = *requestIter; if(!request) { DYSECTWARN(true, "Invalid request in request queue"); break; } if(request->type == DisableType) { sortedQueue.push_back(request); } else { sortedQueue.push_front(request); } } if (sortedQueue.size() == 0) return true; DYSECTVERBOSE(true, "Handling %d process requests", sortedQueue.size()); deque<ProbeRequest*>::iterator sortedRequestIter = sortedQueue.begin(); for(int i = 0; sortedRequestIter != sortedQueue.end(); sortedRequestIter++) { ProbeRequest* request = *sortedRequestIter; if(!request) { DYSECTWARN(true, "Invalid request in request queue"); break; } DYSECTVERBOSE(true, "processRequests() %d", i++); Probe* probe = request->probe; if(!probe) { DYSECTWARN(false, "Probe not found for disable request!"); break; } ProcessSet::ptr waitingProcs = request->scope; if(waitingProcs && waitingProcs->size() > 0) { DYSECTVERBOSE(true, "Adding %d request processes to %d continue set...", waitingProcs->size(), continueSet->size()); continueSet = continueSet->set_union(waitingProcs); } ProcessSet::ptr operationSet = ProcessSet::newProcessSet(); ProcessSet::ptr stopSet = ProcessSet::newProcessSet(); ProcessSet::ptr scope = request->scope; if(scope && scope->size() > 0) { DYSECTVERBOSE(true, "Adding processes from scope set (%d) to affected procs (%d)", scope->size(), operationSet->size()); operationSet = operationSet->set_union(scope); } // // Filter out detached // operationSet = ProcessMgr::filterDetached(operationSet); stopSet = ProcessMgr::filterDetached(stopSet); DYSECTVERBOSE(true, "%d procs in op set, %d procs in stop set", operationSet->size(), stopSet->size()); // // Stop processes // stopSet = operationSet->getAnyThreadRunningSubset(); if(stopSet && stopSet->size() > 0) { DYSECTVERBOSE(true, "Stopping %d processes", stopSet->size()); stopSet->stopProcs(); } // // Carry out operations // if(operationSet && operationSet->size() > 0) { if(request->type == DisableType) { DYSECTVERBOSE(true, "Disabling %d processes", operationSet->size()); probe->disable(operationSet); } else { DYSECTVERBOSE(true, "Enabling %d processes", operationSet->size()); probe->enableChildren(operationSet); } } // // Processes must be started when all operations have been carried out. // if(operationSet && operationSet->size() > 0) { continueSet = continueSet->set_union(operationSet); } delete(request); } continueSet = ProcessMgr::filterDetached(continueSet); if(continueSet && continueSet->size() > 0) { DYSECTVERBOSE(true, "Continuing %d processes", continueSet->size()); if(continueSet->size() == 1) { ProcessSet::iterator procIter = continueSet->begin(); Process::ptr process = *procIter; DYSECTVERBOSE(true, "Continuing process %d", process->getPid()); } continueSet->continueProcs(); } DYSECTVERBOSE(true, "Done handling requests"); return true; }
DysectAPI::DysectErrorCode Frontend::listen() { int ret; int idle = 0; // Install handler for (ctrl-c) abort // signal(SIGINT, Frontend::interrupt); // printf("Waiting for events (! denotes captured event)\n"); printf("Hit <enter> to stop session\n"); fflush(stdout); { do { // select() overwrites fd_set with ready fd's // Copy fd_set structure fd_set fdRead = Domain::getFdSet(); if(breakOnEnter) FD_SET(0, &fdRead); //STDIN struct timeval timeout; timeout.tv_sec = Frontend::selectTimeout; timeout.tv_usec = 0; ret = select(Domain::getMaxFd() + 1, &fdRead, NULL, NULL, &timeout); if(ret < 0) { //return Err::warn(DysectAPI::Error, "select() failed to listen on file descriptor set."); return DysectAPI::OK; } if(FD_ISSET(0, &fdRead) && breakOnEnter) { Err::info(true, "Stopping session - enter key was hit"); break; } // Look for owners vector<Domain*> doms = Domain::getFdsFromSet(fdRead); if(doms.size() == 0) { if(Frontend::breakOnTimeout && (--Frontend::numEvents < 0)) { Err::info(true, "Stopping session - increase numEvents for longer sessions"); break; } } else { printf("\n"); fflush(stdout); } for(int i = 0; i < doms.size(); i++) { Domain* dom = doms[i]; PacketPtr packet; int tag; if(!dom->getStream()) { return Err::warn(Error, "Stream not available for domain %x", dom->getId()); } do { ret = dom->getStream()->recv(&tag, packet, false); if(ret == -1) { return Err::warn(Error, "Receive error"); } else if(ret == 0) { break; } int count; char *payload; int len; if(packet->unpack("%d %auc", &count, &payload, &len) == -1) { return Err::warn(Error, "Unpack error"); } if(Domain::isProbeEnabledTag(tag)) { Domain* dom = 0; if(!Domain::getDomainFromTag(dom, tag)) { Err::warn(false, "Could not get domain from tag %x", tag); } else { //Err::info(true, "[%d] Probe %x enabled (payload size %d)", count, dom->getId(), len); //Err::info(true, "[%d] Probe %x enabled", count, dom->getId()); } Probe* probe = dom->owner; if(!probe) { Err::warn(false, "Probe object not found for %x", dom->getId()); } else { probe->handleActions(count, payload, len); } // Empty bodied probe // Check wether backends are waiting for releasing processes if(dom->isBlocking()) { dom->sendContinue(); } } } while(1); dom->getStream()->clear_DataNotificationFd(); } } while(running); } }
DysectAPI::DysectErrorCode Backend::prepareProbes(struct DysectBEContext_t* context, bool pending) { if(!pending) { assert(context); assert(context->walkerSet); walkerSet = context->walkerSet; Domain::setBEContext(context); DysectAPI::DaemonHostname = context->hostname; } vector<Probe*> roots, removePending; if(pending) roots = ProbeTree::getPendingRoots(); else roots = ProbeTree::getRoots(); for(int i = 0; i < roots.size(); i++) { Probe* probe = roots[i]; // Prepare all streams ie. ensure all domain ids and tags are created // for stream -> domain binding if(probe->prepareStream(recursive) != OK) { DYSECTWARN(Error, "Error occured while preparing streams"); if(!pending) ProbeTree::addPendingRoot(probe); continue; } if(probe->prepareEvent(recursive) != OK) { if(!pending) { DYSECTLOG(Error, "Error occured while preparing events, adding to pending events"); ProbeTree::addPendingRoot(probe); } continue; DYSECTWARN(Error, "Error occured while preparing events"); } DYSECTVERBOSE(true, "Starting preparation of conditions"); if(probe->prepareCondition(recursive) != OK) { DYSECTWARN(Error, "Error occured while preparing conditions"); if(!pending) ProbeTree::addPendingRoot(probe); continue; } if(probe->prepareAction(recursive) != OK) { DYSECTWARN(Error, "Error occured while preparing actions"); if(!pending) ProbeTree::addPendingRoot(probe); continue; } if(pending) { DYSECTVERBOSE(true, "Enabled pending probe %x", probe); removePending.push_back(probe); } } if(pending) { if(removePending.size() == 0) return OK; for(int i = 0; i < removePending.size(); i++) ProbeTree::removePendingRoot(removePending[i]); } // Add all domains to missing bindings map<tag_t, Domain*> domainMap = Domain::getDomainMap(); map<tag_t, Domain*>::iterator domainIter = domainMap.begin(); for(;domainIter != domainMap.end(); domainIter++) { tag_t domainId = domainIter->first; Domain* dom = domainIter->second; if(dom->anyTargetsAttached()) { DYSECTVERBOSE(true, "Missing domain: %x", domainId); missingBindings.insert(domainId); } } // List generated - wait for incoming frontend init packages if(missingBindings.empty()) { state = ready; if(controlStream != 0) { DYSECTVERBOSE(true, "No domains need to be bound - send ack"); ackBindings(); } } else { state = bindingStreams; } return OK; }
/** * Create the underlying system component(s). */ void Probe::addToSystem(MultibodySystem& system) const { Super::addToSystem(system); if (isDisabled()) return; // Make writable briefly so we can finalize the Probe to include // references to the allocated System resources. Probe* mutableThis = const_cast<Probe*>(this); // --------------------------------------------------------------------- // Create a <double> Measure of the value to be probed (operand). // For now, this is scalarized, i.e. a separate Measure is created // for each probe input element in the Vector. // --------------------------------------------------------------------- // save for when we can directly operate on Vector SimTK::Measures //ProbeMeasure<SimTK::Vector> beforeOperationValueVector(system, *this); int npi = getNumProbeInputs(); SimTK::Array_<ProbeMeasure<double> > beforeOperationValues; mutableThis->afterOperationValues.resize(npi); for (int i=0; i<npi; ++i) { ProbeMeasure<double> tmpPM(system, *this, i); beforeOperationValues.push_back(tmpPM); } // Assign the correct (operation) Measure subclass to the operand // ============================================================== // --------------------------------------------------------------------- // Return the original probe value (no operation) // --------------------------------------------------------------------- if (getOperation() == "value") { for (int i=0; i<npi; ++i) { mutableThis->afterOperationValues[i] = beforeOperationValues[i]; } } // --------------------------------------------------------------------- // Integrate the probe value // --------------------------------------------------------------------- else if (getOperation() == "integrate") { // check to see that size of initial condition vector // is the same size as the data being integrated. if (getInitialConditions().size() != getProbeOutputLabels().getSize()) { stringstream errorMessage; errorMessage << getConcreteClassName() << "(" + getName() << "): Mismatch between the size of the data labels corresponding to the " "size of the data vector being integrated (" << getProbeOutputLabels().getSize() << ") and size of initial conditions vector (" << getInitialConditions().size() << ").\nAssuming an initial condition vector of " << getProbeOutputLabels().getSize() << " zeros." << endl; cout << errorMessage.str() << endl; SimTK::Vector newInitCond(getProbeOutputLabels().getSize()); newInitCond = 0; Probe* mutableThis = const_cast<Probe*>(this); mutableThis->setInitialConditions(newInitCond); //throw (Exception(errorMessage.str())); } for (int i=0; i<getNumProbeInputs(); ++i) { //Measure::Constant initCond(system, getInitialConditions()(i)); // init cond is handled as a special case in getProbeOutputs() Measure::Constant initCond(system, 0.0); mutableThis->afterOperationValues[i] = Measure::Integrate( system, beforeOperationValues[i], initCond); } } // --------------------------------------------------------------------- // Differentiate the probe value // --------------------------------------------------------------------- else if (getOperation() == "differentiate") { for (int i=0; i<getNumProbeInputs(); ++i) { mutableThis->afterOperationValues[i] = Measure::Differentiate( system, beforeOperationValues[i]); } } // --------------------------------------------------------------------- // Get the minimum of the probe value // --------------------------------------------------------------------- else if (getOperation() == "minimum") { for (int i=0; i<getNumProbeInputs(); ++i) { mutableThis->afterOperationValues[i] = Measure::Minimum( system, beforeOperationValues[i]); } } // --------------------------------------------------------------------- // Get the absolute minimum of the probe value // --------------------------------------------------------------------- else if (getOperation() == "minabs") { for (int i=0; i<getNumProbeInputs(); ++i) { mutableThis->afterOperationValues[i] = Measure::MinAbs( system, beforeOperationValues[i]); } } // --------------------------------------------------------------------- // Get the maximum of the probe value // --------------------------------------------------------------------- else if (getOperation() == "maximum") { for (int i=0; i<getNumProbeInputs(); ++i) { mutableThis->afterOperationValues[i] = Measure::Maximum( system, beforeOperationValues[i]); } } // --------------------------------------------------------------------- // Get the absolute maximum of the probe value // --------------------------------------------------------------------- else if (getOperation() == "maxabs") { for (int i=0; i<getNumProbeInputs(); ++i) { mutableThis->afterOperationValues[i] = Measure::MaxAbs( system, beforeOperationValues[i]); } } // --------------------------------------------------------------------- // Throw exception (invalid operation) // --------------------------------------------------------------------- else { stringstream errorMessage; errorMessage << getConcreteClassName() << ": Invalid probe operation: " << getOperation() << ". Currently supports 'value', 'integrate', 'differentiate', " "'minimum', 'minabs', 'maximum', 'maxabs'." << endl; throw (Exception(errorMessage.str())); } }
DysectAPI::DysectErrorCode Backend::prepareProbes(struct DysectBEContext_t* context) { assert(context); assert(context->walkerSet); walkerSet = context->walkerSet; Domain::setBEContext(context); DysectAPI::DaemonHostname = context->hostname; vector<Probe*> roots = ProbeTree::getRoots(); for(int i = 0; i < roots.size(); i++) { Probe* probe = roots[i]; // Prepare all streams ie. ensure all domain ids and tags are created // for stream -> domain binding if(probe->prepareStream(recursive) != OK) { Err::warn(Error, "Error occured while preparing streams"); } if(probe->prepareEvent(recursive) != OK) { Err::warn(Error, "Error occured while preparing events"); } Err::verbose(true, "Starting preparation of conditions"); if(probe->prepareCondition(recursive) != OK) { Err::warn(Error, "Error occured while preparing conditions"); } if(probe->prepareAction(recursive) != OK) { Err::warn(Error, "Error occured while preparing actions"); } } // Add all domains to missing bindings map<tag_t, Domain*> domainMap = Domain::getDomainMap(); map<tag_t, Domain*>::iterator domainIter = domainMap.begin(); for(;domainIter != domainMap.end(); domainIter++) { tag_t domainId = domainIter->first; Domain* dom = domainIter->second; if(dom->anyTargetsAttached()) { Err::verbose(true, "Missing domain: %x", domainId); missingBindings.insert(domainId); } } // List generated - wait for incoming frontend init packages if(missingBindings.empty()) { state = ready; if(controlStream != 0) { Err::verbose(true, "No domains need to be bound - send ack"); ackBindings(); } } else { state = bindingStreams; } return OK; }
DysectAPI::DysectErrorCode Backend::relayPacket(PacketPtr* packet, int tag, Stream* stream) { if(tag == DysectGlobalReadyTag){ // Stream to respond when all streams have been bound if(controlStream != 0) { return Err::warn(Error, "Control stream already set"); } controlStream = stream; if((state == ready) && (!streamBindAckSent)) { ackBindings(); } return OK; } switch(state) { case bindingStreams: { if(Domain::isInitTag(tag)) { if(bindStream(tag, stream) != OK) { return Err::warn(StreamError, "Failed to bind stream!"); } } else { assert(!"Save packet until all streams have been bound to domains - not yet supported"); } } break; case ready: { if(tag == DysectGlobalStartTag) { enableProbeRoots(); } else { if(Domain::isContinueTag(tag)) { Domain* dom = 0; if(!Domain::getDomainFromTag(dom, tag)) { Err::warn(false, "Domain for tag %x could not be found", tag); } else { Probe* probe = dom->owner; if(!probe) { Err::warn(false, "Probe for tag %x could not be found", tag); } else { ProcessSet::ptr lprocset = probe->getWaitingProcs(); // OK to call - we are not in callback probe->enableChildren(lprocset); probe->releaseWaitingProcs(); } } } } } break; default: return InvalidSystemState; break; } return OK; }
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; }