def __init__(self, app, probes): """ Creates a new instance of Abstract runtime The constructor also instantiates caches for pmu events and topdown metrics :param app: an instance of xpedite app, to interact with target application :type app: xpedite.profiler.app.XpediteApp :param probes: List of probes to be enabled for the current profile session """ from xpedite.profiler.resolver import ProbeResolver from xpedite.pmu.eventsDb import EventsDbCache from xpedite.pmu.topdown import TopdownCache from xpedite.profiler.app import pingApp pingApp(app) self.app = app self.probes = probes self.profiles = None self.probeResolver = ProbeResolver() self.cpuInfo = None self.eventsDbCache = EventsDbCache() self.topdownCache = TopdownCache(self.eventsDbCache) self.topdownMetrics = None self.eventSet = None
class AbstractRuntime(object): """ Base class for xpedite runtime to orchestrate a profile session. The Abstract runtime provides implemetation to resolve/enable probes and pmu events """ def __init__(self, app, probes): """ Creates a new instance of Abstract runtime The constructor also instantiates caches for pmu events and topdown metrics :param app: an instance of xpedite app, to interact with target application :type app: xpedite.profiler.app.XpediteApp :param probes: List of probes to be enabled for the current profile session """ from xpedite.profiler.resolver import ProbeResolver from xpedite.pmu.eventsDb import EventsDbCache from xpedite.pmu.topdown import TopdownCache from xpedite.profiler.app import pingApp pingApp(app) self.app = app self.probes = probes self.probeResolver = ProbeResolver() self.cpuInfo = None self.eventsDbCache = EventsDbCache() self.topdownCache = TopdownCache(self.eventsDbCache) self.topdownMetrics = None self.eventSet = None @staticmethod def formatProbes(probes): """ Formats a list of probes to string :param probes: List of probes to be enabled for the current profile session """ probeStr = '' for probe in probes: probeStr = probeStr + '\n\t{}'.format(probe) return probeStr def enableProbes(self, probes): """ Enables the list of given probes :param probes: List of probes to be enabled for the current profile session """ from xpedite.profiler.probeAdmin import ProbeAdmin LOGGER.debug('Enabling probes %s', self.formatProbes(probes)) if probes: if self.eventSet: errMsg = ProbeAdmin.enablePMU(self.app, self.eventSet) if errMsg: msg = 'failed to enable PMU ({})'.format(errMsg) LOGGER.error(msg) raise Exception(msg) (errCount, errMsg) = ProbeAdmin.updateProbes(self.app, probes, targetState=True) if errCount > 0: msg = 'failed to enable probes ({} error(s))\n{}'.format( errCount, errMsg) LOGGER.error(msg) raise Exception(msg) else: LOGGER.warn( 'failed to enable probes - Invalid or empty probes argument') def resolveProbes(self, probes): """ Checks the validity of the list of given probes :param probes: List of probes to be enabled for the current profile session """ from xpedite.types.probe import AnchoredProbe anchoredProbes = [] LOGGER.debug('Resolving probes %s', self.formatProbes(probes)) for probe in probes: if not probe.isAnchored(): resolvedProbes = self.probeResolver.resolveAnchoredProbe( self.app, probe) if resolvedProbes: for rp in resolvedProbes: anchoredProbe = AnchoredProbe(probe.name, filePath=rp.filePath, lineNo=rp.lineNo, attributes=rp.attributes, isActive=rp.isActive, sysName=rp.sysName) anchoredProbes.append(anchoredProbe) LOGGER.debug('Resolved probe %s to anchored probe %s', probe, anchoredProbe) else: raise Exception( 'probe {} cannot be located in app. Please check if it\'s a valid probe' .format(probe.sysName)) else: anchoredProbes.append(probe) return anchoredProbes @staticmethod def resolveEvents(eventsDb, cpuSet, events): """ Resolves a list of given pmu events from events database :param eventsDb: Handle to database of PMU events for the target cpu :param events: List of PMU events to be enabled for the current profile session :param cpuSet: List of cpu, where the userspace pmu collection will be enabled """ from xpedite.pmu.pmuctrl import PMUCtrl return PMUCtrl.resolveEvents(eventsDb, cpuSet, events) @staticmethod def aggregatePmc(pmc): """ Aggreagtes given pmu events to create a unique list of events :param pmc: PMU events to be enabled for the current profile session """ from collections import OrderedDict events = OrderedDict() for counter in pmc: if isinstance(counter, list): for event in counter: events.update({event: 0}) else: events.update({counter: 0}) return events.keys() def resolveTopdownMetrics(self, pmc): """ Resolves pmu events for given topdown metrics. The method resolves a list of pmu events, for one or more nodes in the topdown hierarchy :param pmc: PMU events to be enabled for the current profile session """ import copy from xpedite.pmu.event import TopdownMetrics from xpedite.pmu.event import Event, TopdownNode, Metric pmc = copy.copy(pmc) topdownNodes = [ i for i, counter in enumerate(pmc) if isinstance(counter, (TopdownNode, Metric)) ] if topdownNodes: topdown = self.topdownCache.get(self.cpuInfo.cpuId) self.topdownMetrics = TopdownMetrics() for index in topdownNodes: node = pmc[index] topdownNode = self.topdownMetrics.add(topdown, node) pmc[index] = [ Event(event.name.title().replace('_', '').replace(' ', ''), event.name) for event in topdownNode.events ] return pmc