use of org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException in project tracecompass by tracecompass.
the class KernelCpuUsageAnalysis method getCpuUsageInRange.
/**
* Get a map of time spent on CPU by various threads during a time range.
*
* @param cpus
* A set of the desired CPUs to get. An empty set gets all the
* cores
* @param start
* Start time of requested range
* @param end
* End time of requested range
* @return A map of TID -> time spent on CPU in the [start, end] interval
* @since 2.0
*/
public Map<String, Long> getCpuUsageInRange(Set<@NonNull Integer> cpus, long start, long end) {
Map<String, Long> map = new HashMap<>();
Map<String, Long> totalMap = new HashMap<>();
ITmfTrace trace = getTrace();
ITmfStateSystem cpuSs = getStateSystem();
if (trace == null || cpuSs == null) {
return map;
}
ITmfStateSystem kernelSs = TmfStateSystemAnalysisModule.getStateSystem(trace, TidAnalysisModule.ID);
if (kernelSs == null) {
return map;
}
/*
* Make sure the start/end times are within the state history, so we
* don't get TimeRange exceptions.
*/
long startTime = Math.max(start, cpuSs.getStartTime());
startTime = Math.max(startTime, kernelSs.getStartTime());
long endTime = Math.min(end, cpuSs.getCurrentEndTime());
endTime = Math.min(endTime, kernelSs.getCurrentEndTime());
long totalTime = 0;
if (endTime < startTime) {
return map;
}
try (ScopeLog scopeLog = new ScopeLog(LOGGER, Level.FINE, "KernelCpuUsageAnalysis#getCpuUsageInRange")) {
// $NON-NLS-1$
/* Get the list of quarks for each CPU and CPU's TIDs */
int cpusNode = cpuSs.getQuarkAbsolute(Attributes.CPUS);
Map<Integer, List<Integer>> tidsPerCpu = new HashMap<>();
for (int cpuNode : cpuSs.getSubAttributes(cpusNode, false)) {
@NonNull final List<@NonNull Integer> cpuSubAttributes = cpuSs.getSubAttributes(cpuNode, false);
if (cpus.isEmpty() || cpus.contains(Integer.parseInt(cpuSs.getAttributeName(cpuNode)))) {
tidsPerCpu.put(cpuNode, cpuSubAttributes);
}
}
/* Query full states at start and end times */
List<ITmfStateInterval> kernelEndState = kernelSs.queryFullState(endTime);
List<ITmfStateInterval> endState = cpuSs.queryFullState(endTime);
List<ITmfStateInterval> kernelStartState = kernelSs.queryFullState(startTime);
List<ITmfStateInterval> startState = cpuSs.queryFullState(startTime);
long countAtStart, countAtEnd;
for (Entry<Integer, List<Integer>> entry : tidsPerCpu.entrySet()) {
int cpuNode = Objects.requireNonNull(entry.getKey());
List<Integer> tidNodes = Objects.requireNonNull(entry.getValue());
String curCpuName = cpuSs.getAttributeName(cpuNode);
long cpuTotal = 0;
/* Get the quark of the thread running on this CPU */
int currentThreadQuark = kernelSs.getQuarkAbsolute(curCpuName);
/* Get the currently running thread on this CPU */
int startThread = kernelStartState.get(currentThreadQuark).getStateValue().unboxInt();
int endThread = kernelEndState.get(currentThreadQuark).getStateValue().unboxInt();
for (int tidNode : tidNodes) {
String curTidName = cpuSs.getAttributeName(tidNode);
int tid = Integer.parseInt(curTidName);
countAtEnd = endState.get(tidNode).getStateValue().unboxLong();
countAtStart = startState.get(tidNode).getStateValue().unboxLong();
if (countAtStart == -1) {
countAtStart = 0;
}
if (countAtEnd == -1) {
countAtEnd = 0;
}
/*
* Interpolate start and end time of threads running at
* those times
*/
if (tid == startThread || startThread == -1) {
ITmfStateInterval threadState = kernelStartState.get(currentThreadQuark);
long runningTime = threadState.getEndTime() - threadState.getStartTime();
long runningEnd = threadState.getEndTime();
countAtStart = interpolateCount(countAtStart, startTime, runningEnd, runningTime);
}
if (tid == endThread) {
long runningTime = kernelEndState.get(currentThreadQuark).getEndTime() - kernelEndState.get(currentThreadQuark).getStartTime();
long runningEnd = kernelEndState.get(currentThreadQuark).getEndTime();
countAtEnd = interpolateCount(countAtEnd, endTime, runningEnd, runningTime);
}
/*
* If startThread is -1, we made the hypothesis that the
* process running at start was the current one. If the
* count is negative, we were wrong in this hypothesis. Also
* if the time at end is 0, it either means the process
* hasn't been on the CPU or that we still don't know who is
* running. In both cases, that invalidates the hypothesis.
*/
if ((startThread == -1) && ((countAtEnd - countAtStart < 0) || (countAtEnd == 0))) {
countAtStart = 0;
}
long currentCount = countAtEnd - countAtStart;
if (currentCount < 0) {
// $NON-NLS-1$
TraceCompassLogUtils.traceInstant(// $NON-NLS-1$
LOGGER, // $NON-NLS-1$
Level.FINE, // $NON-NLS-1$
"Negative count", // $NON-NLS-1$
"CPU", // $NON-NLS-1$
curCpuName, // $NON-NLS-1$
"tid", // $NON-NLS-1$
curTidName, // $NON-NLS-1$
"startTime", // $NON-NLS-1$
startTime, // $NON-NLS-1$
"endTime", // $NON-NLS-1$
endTime, // $NON-NLS-1$
"countAtStart", // $NON-NLS-1$
countAtStart, "countAtEnd", // $NON-NLS-1$
countAtEnd);
currentCount = 0;
} else if (currentCount > endTime - startTime) {
// $NON-NLS-1$
TraceCompassLogUtils.traceInstant(// $NON-NLS-1$
LOGGER, // $NON-NLS-1$
Level.FINE, // $NON-NLS-1$
"CPU usage over 100%", // $NON-NLS-1$
"CPU", // $NON-NLS-1$
curCpuName, // $NON-NLS-1$
"tid", // $NON-NLS-1$
curTidName, // $NON-NLS-1$
"startTime", // $NON-NLS-1$
startTime, // $NON-NLS-1$
"CPU time", // $NON-NLS-1$
currentCount, // $NON-NLS-1$
"elapsed time", // $NON-NLS-1$
endTime - startTime, "usage", // $NON-NLS-1$
currentCount * 100.0 / (endTime - startTime));
currentCount = 0;
}
cpuTotal += currentCount;
map.put(curCpuName + SPLIT_STRING + curTidName, currentCount);
addToMap(totalMap, curTidName, currentCount);
totalTime += (currentCount);
}
map.put(curCpuName, cpuTotal);
}
/* Add the totals to the map */
for (Entry<String, Long> entry : totalMap.entrySet()) {
map.put(TOTAL + SPLIT_STRING + entry.getKey(), entry.getValue());
}
map.put(TOTAL, totalTime);
} catch (TimeRangeException | AttributeNotFoundException e) {
/*
* Assume there is no events or the attribute does not exist yet,
* nothing will be put in the map.
*/
} catch (StateValueTypeException | StateSystemDisposedException e) {
/*
* These other exception types would show a logic problem, so they
* should not happen.
*/
// $NON-NLS-1$
Activator.getDefault().logError("Error getting CPU usage in a time range", e);
}
return map;
}
use of org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException in project tracecompass by tracecompass.
the class KernelThreadInformationProvider method getProcessId.
/**
* Get the process ID of a thread
*
* @param module
* The kernel analysis instance to run this method on
* @param threadId
* The ID of the thread for which to get the process ID
* @param ts
* The timestamp at which to get the parent
* @return The process ID or {@code null} if the pid is not found.
* @since 2.5
*/
@Nullable
public static Integer getProcessId(KernelAnalysisModule module, Integer threadId, long ts) {
ITmfStateSystem ss = module.getStateSystem();
if (ss == null) {
return null;
}
try {
int pidNode = ss.optQuarkAbsolute(Attributes.THREADS, threadId.toString());
if (pidNode == ITmfStateSystem.INVALID_ATTRIBUTE) {
/* The thread is invalid, return null */
return null;
}
pidNode = ss.optQuarkRelative(pidNode, Attributes.PID);
if (pidNode == ITmfStateSystem.INVALID_ATTRIBUTE) {
/* The attribute is not there, thread is the process */
return threadId;
}
ITmfStateInterval pidInterval = ss.querySingleState(ts, pidNode);
Object pid = pidInterval.getValue();
if (pid instanceof Integer) {
return (Integer) pid;
}
} catch (StateSystemDisposedException | TimeRangeException e) {
}
return null;
}
use of org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException in project tracecompass by tracecompass.
the class KernelStateProvider method eventHandle.
@Override
protected void eventHandle(@Nullable ITmfEvent event) {
if (event == null) {
return;
}
final String eventName = event.getName();
try {
final ITmfStateSystemBuilder ss = NonNullUtils.checkNotNull(getStateSystemBuilder());
/*
* Feed event to the history system if it's known to cause a state
* transition.
*/
KernelEventHandler handler = fEventNames.get(eventName);
if (handler == null) {
if (isSyscallExit(eventName)) {
handler = fSysExitHandler;
} else if (isSyscallEntry(eventName)) {
handler = fSysEntryHandler;
}
}
if (handler != null) {
handler.handleEvent(ss, event);
}
} catch (AttributeNotFoundException ae) {
/*
* This would indicate a problem with the logic of the manager here,
* so it shouldn't happen.
*/
// $NON-NLS-1$
Activator.getDefault().logError("Attribute not found: " + ae.getMessage(), ae);
} catch (TimeRangeException tre) {
/*
* This would happen if the events in the trace aren't ordered
* chronologically, which should never be the case ...
*/
Activator.getDefault().logError(// $NON-NLS-1$
"TimeRangeExcpetion caught in the state system's event manager.\n" + "Are the events in the trace correctly ordered?\n" + tre.getMessage(), // $NON-NLS-1$
tre);
} catch (StateValueTypeException sve) {
/*
* This would happen if we were trying to push/pop attributes not of
* type integer. Which, once again, should never happen.
*/
// $NON-NLS-1$
Activator.getDefault().logError("State value error: " + sve.getMessage(), sve);
}
}
use of org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException in project tracecompass by tracecompass.
the class ThreadStatusDataProvider method fetchArrows.
@Override
@NonNull
public TmfModelResponse<@NonNull List<@NonNull ITimeGraphArrow>> fetchArrows(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, IProgressMonitor monitor) {
ITmfStateSystem ss = fModule.getStateSystem();
if (ss == null) {
return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.ANALYSIS_INITIALIZATION_FAILED);
}
List<@NonNull ITimeGraphArrow> linkList = new ArrayList<>();
/**
* MultiMap of the current thread intervals, grouped by CPU, by increasing start
* time.
*/
TreeMultimap<Integer, ITmfStateInterval> currentThreadIntervalsMap = TreeMultimap.create(Comparator.naturalOrder(), Comparator.comparing(ITmfStateInterval::getStartTime));
List<Integer> quarks = ss.getQuarks(Attributes.CPUS, WILDCARD, Attributes.CURRENT_THREAD);
TimeQueryFilter filter = FetchParametersUtils.createTimeQuery(fetchParameters);
Collection<Long> times = getTimes(ss, filter);
try {
/* Do the actual query */
for (ITmfStateInterval interval : ss.query2D(quarks, times)) {
if (monitor != null && monitor.isCanceled()) {
return new TmfModelResponse<>(null, ITmfResponse.Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
}
currentThreadIntervalsMap.put(interval.getAttribute(), interval);
}
/* Get the arrows. */
for (Collection<ITmfStateInterval> currentThreadIntervals : currentThreadIntervalsMap.asMap().values()) {
if (monitor != null && monitor.isCanceled()) {
return new TmfModelResponse<>(null, ITmfResponse.Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
}
linkList.addAll(createCpuArrows(ss, (NavigableSet<ITmfStateInterval>) currentThreadIntervals));
}
} catch (TimeRangeException | StateSystemDisposedException e) {
return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, String.valueOf(e.getMessage()));
}
return new TmfModelResponse<>(linkList, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}
use of org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException in project tracecompass by tracecompass.
the class CallsiteStateProvider method eventHandle.
@Override
protected void eventHandle(@NonNull ITmfEvent event) {
ITmfStateSystemBuilder ssb = Objects.requireNonNull(getStateSystemBuilder());
List<ITmfCallsite> callsites = null;
for (ITmfEventAspect<?> aspect : fCsAspects) {
Object result = aspect.resolve(event);
if (result instanceof List) {
callsites = (List<ITmfCallsite>) result;
break;
}
}
if (callsites == null || callsites.isEmpty()) {
return;
}
int root = getRootAttribute(event);
if (root == ITmfStateSystem.INVALID_ATTRIBUTE) {
return;
}
int filesQuark = ssb.getQuarkRelativeAndAdd(root, FILES);
int linesQuark = ssb.getQuarkRelativeAndAdd(root, LINES);
long time = event.getTimestamp().toNanos();
try {
Integer prevFile = (Integer) ssb.queryOngoing(filesQuark);
ssb.modifyAttribute(time, (int) (fInterner.intern(ssb, callsites.get(0).getFileName(), fSourceQuark) - ssb.getStartTime()), filesQuark);
Integer nextFile = (Integer) ssb.queryOngoing(filesQuark);
Long lineNo = callsites.get(0).getLineNo();
Integer prevLine = (Integer) ssb.queryOngoing(filesQuark);
Integer nextLine = lineNo == null ? null : Integer.valueOf(lineNo.intValue());
// have at least one change if a trace has two identical callsites.
if (Objects.equals(prevLine, nextLine) && Objects.equals(prevFile, nextFile)) {
ssb.modifyAttribute(time, (Object) null, linesQuark);
}
ssb.modifyAttribute(time, nextLine, linesQuark);
} catch (StateValueTypeException | IndexOutOfBoundsException | TimeRangeException e) {
Activator.logError(e.getMessage(), e);
}
}
Aggregations