def __init__(self, name, cpuInfo, probes, topdownMetrics, events): """ Constructs a loader, that builds transactions based on probe bounds (begin/end probes) :param name: Name of the profiling session :param cpuInfo: Cpu info of the host running target app :param probes: List of probes enabled for the profiling session :param topdownMetrics: Top down metrics to be computed :param events: PMU events collected for the profile session """ AbstractTxnLoader.__init__(self, name, cpuInfo, probes, topdownMetrics, events) self.nextTxnId = 0 self.ephemeralCounters = [] self.nextFragmentId = 0 self.fragments = TxnFragments() self.resumeFragment = None self.suspendingTxn = False
class BoundedTxnLoader(AbstractTxnLoader): """Loads transactions bounded by well defined begin/end probes""" def __init__(self, name, cpuInfo, probes, topdownMetrics, events): """ Constructs a loader, that builds transactions based on probe bounds (begin/end probes) :param name: Name of the profiling session :param cpuInfo: Cpu info of the host running target app :param probes: List of probes enabled for the profiling session :param topdownMetrics: Top down metrics to be computed :param events: PMU events collected for the profile session """ AbstractTxnLoader.__init__(self, name, cpuInfo, probes, topdownMetrics, events) self.nextTxnId = 0 self.ephemeralCounters = [] self.nextFragmentId = 0 self.fragments = TxnFragments() self.resumeFragment = None self.suspendingTxn = False def appendTxn(self, txn): """ Inserts or updates transaction to collection :param txn: Transaction to be appended """ if not (self.resumeFragment or self.suspendingTxn): self.nextTxnId += 1 txn.txnId = self.nextTxnId AbstractTxnLoader.appendTxn(self, txn) def loadCounter(self, counter): """ Associates the given counter with a transaction :param counter: counter with probe and sample data :type counter: xpedite.types.Counter """ self.processedCounterCount += 1 userProbe = self.probeMap.get(counter.probe, counter.probe) if self.currentTxn: if userProbe.canBeginTxn or userProbe.canResumeTxn: if self.currentTxn.hasEndProbe or userProbe.canResumeTxn: if self.ephemeralCounters: self.nonTxnCounters.extend(self.ephemeralCounters) self.ephemeralCounters = [] self.appendTxn(self.currentTxn) self.currentTxn = self.buildTxn(counter, userProbe.canResumeTxn) else: self.currentTxn.addCounter(counter, False) elif userProbe.canEndTxn or userProbe.canSuspendTxn: if self.ephemeralCounters: for eCounter in self.ephemeralCounters: self.currentTxn.addCounter(eCounter, False) self.ephemeralCounters = [] self.currentTxn.addCounter(counter, True) if userProbe.canSuspendTxn: self.suspendingTxn |= userProbe.canSuspendTxn linkId = '{:x}{}'.format(counter.tsc, self.tlsAddr) self.fragments.addSuspendFragment(linkId, self.currentTxn, self.resumeFragment) else: if self.currentTxn.hasEndProbe: self.ephemeralCounters.append(counter) else: self.currentTxn.addCounter(counter, False) else: if userProbe.canBeginTxn or userProbe.canResumeTxn: self.currentTxn = self.buildTxn(counter, userProbe.canResumeTxn) if self.ephemeralCounters: self.nonTxnCounters.extend(self.ephemeralCounters) self.ephemeralCounters = [] elif userProbe.canEndTxn or userProbe.canSuspendTxn: compromisedTxn = self.buildTxn(counter) for eCounter in self.ephemeralCounters: compromisedTxn.addCounter(eCounter, False) self.compromisedTxns.append(compromisedTxn) self.ephemeralCounters = [] else: self.ephemeralCounters.append(counter) def buildTxn(self, counter, resumeTxn=False): """ Constructs a new transaction instance :param counter: counter with probe and sample data """ txnId = None self.suspendingTxn = False if resumeTxn: txnId = counter.data txn = Transaction(counter, txnId) self.resumeFragment = self.fragments.addResumeFragment(txnId, txn) return txn self.resumeFragment = None self.nextFragmentId += 1 return Transaction(counter, self.nextFragmentId) def endLoad(self): """Marks end of the current load session""" if self.currentTxn: if self.currentTxn.hasEndProbe: self.appendTxn(self.currentTxn) else: self.compromisedTxns.append(self.currentTxn) self.currentTxn = None def endCollection(self): """Ends loading of samples from multiple threads of a target process""" txns = self.fragments.join(self.nextTxnId) for txn in txns: AbstractTxnLoader.appendTxn(self, txn)