blob: 426a32c9d4135319d2f21a79fc8b6ecfdea6ab9c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2015 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Alexandre Montplaisir - Initial API and implementation
* Matthew Khouzam - Add the task state system from figure 3 from the spec
*******************************************************************************/
package org.eclipse.tracecompass.btf.core.analysis;
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.btf.core.event.BtfEvent;
import org.eclipse.tracecompass.btf.core.trace.BtfColumnNames;
import org.eclipse.tracecompass.btf.core.trace.BtfTrace;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
/**
* State provider for the default BTF analysis.
*
* The generated attribute tree will look like this:
*
* <pre>
* {root}
* +- Cores
* | +- Core 1 (not running/Name of the running Task)
* | +- Core 2 (not running/Name of the running Task)
* |
* +- Tasks
* +- Task A
* | +- Core 1 (not running/running/suspended)
* | | +- Runnable A1 (not running/running/suspended)
* | | +- Runnable A2 (not running/running/suspended)
* | +- Core 2
* | | +- Runnable A1
* | | +- Runnable A2
* | +- ActiveCore
* |
* +- Task B
* +- Core 1
* | +- Runnable B1
* | +- Runnable B2
* +- Core 2
* | +- Runnable B1
* | +- Runnable B2
* +- ActiveCore
* </pre>
*
* @author Alexandre Montplaisir
*/
public class BtfStateProvider extends AbstractTmfStateProvider {
private static final int PROVIDER_VERSION = 3;
private static class TmfNamedStateValue {
private final String fName;
private final @NonNull TmfStateValue fValue;
public TmfNamedStateValue(@NonNull TmfStateValue value, String name) {
fValue = value;
fName = name;
}
public @NonNull TmfStateValue getValue() {
return fValue;
}
@Override
public String toString() {
return fName;
}
}
private static final TmfNamedStateValue STATE_CORE_IDLE = new TmfNamedStateValue(TmfStateValue.newValueInt(0), "Idle"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_NOT_RUNNING = new TmfNamedStateValue(TmfStateValue.nullValue(), "Not Running"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_RUNNING = new TmfNamedStateValue(TmfStateValue.newValueInt((1)), "RUNNING"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_SUSPENDED = new TmfNamedStateValue(TmfStateValue.newValueInt((2)), "SUSPENDED"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_TASK_ACTIVE = new TmfNamedStateValue(TmfStateValue.newValueInt((4)), "Active"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_TASK_READY = new TmfNamedStateValue(TmfStateValue.newValueInt((5)), "Ready"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_TASK_RUNNING = new TmfNamedStateValue(TmfStateValue.newValueInt((6)), "Task Running"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_TASK_WAITING = new TmfNamedStateValue(TmfStateValue.newValueInt((7)), "Waiting"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_TASK_PARKING = new TmfNamedStateValue(TmfStateValue.newValueInt((8)), "Parking"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_TASK_POLLING = new TmfNamedStateValue(TmfStateValue.newValueInt((9)), "Polling"); //$NON-NLS-1$
private static final TmfNamedStateValue STATE_TASK_TERMINATED = new TmfNamedStateValue(TmfStateValue.nullValue(), "Terminated"); //$NON-NLS-1$
private static final String ENTITY_CORE = "Core"; //$NON-NLS-1$
private static final String ENTITY_TASK = "TASK"; //$NON-NLS-1$
// private static final String ENTITY_RUNNABLE = "RUNNABLE";
private static final String ATTRIBUTE_TASKS = "Tasks"; //$NON-NLS-1$
private static final String ATTRIBUTE_CORES = "Cores"; //$NON-NLS-1$
private static final String ATTRIBUTE_ACTIVE_CORE = "ActiveCore"; //$NON-NLS-1$
/**
* Constructor
*
* @param trace
* The trace for which we will be building this state system
*/
public BtfStateProvider(BtfTrace trace) {
super(trace, "Btf State Provider"); //$NON-NLS-1$
}
@Override
public BtfTrace getTrace() {
return (BtfTrace) super.getTrace();
}
@Override
public int getVersion() {
return PROVIDER_VERSION;
}
@Override
public ITmfStateProvider getNewInstance() {
return new BtfStateProvider(getTrace());
}
@Override
protected void eventHandle(ITmfEvent ev) {
if (!(ev instanceof BtfEvent)) {
return;
}
BtfEvent event = (BtfEvent) ev;
final ITmfStateSystemBuilder ssb = checkNotNull(getStateSystemBuilder());
final long ts = event.getTimestamp().getValue();
final String eventType = (String) event.getContent().getField(BtfColumnNames.EVENT.toString()).getValue();
final String source = event.getSource();
final String target = event.getTarget();
String task;
int quark;
try {
switch (eventType) {
case "activate": //$NON-NLS-1$
updateTaskStateSystem(ssb, ts, event, STATE_TASK_ACTIVE);
break;
case "start": //$NON-NLS-1$
case "resume": //$NON-NLS-1$
updateTaskStateSystem(ssb, ts, event, STATE_TASK_RUNNING);
if (source.startsWith(ENTITY_CORE)) {
String core = source;
task = target;
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core);
ssb.modifyAttribute(ts, STATE_RUNNING.getValue().unboxValue(), quark);
/* Mark this task as active in the ActiveCore attribute */
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, ATTRIBUTE_ACTIVE_CORE);
ssb.modifyAttribute(ts, core, quark);
/* Mark this task as active in the Cores/* attribute */
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_CORES, core);
/* Until the view can display the string */
ssb.modifyAttribute(ts, STATE_RUNNING.getValue().unboxValue(), quark);
} else if (source.startsWith(ENTITY_TASK)) {
task = source;
String runnable = target;
String core = getCoreOfTask(ssb, task);
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core, runnable);
ssb.modifyAttribute(ts, STATE_RUNNING.getValue().unboxValue(), quark);
}
break;
case "suspend": //$NON-NLS-1$
/* "suspend" events only happen on Tasks */
if (source.startsWith(ENTITY_TASK)) {
task = source;
String runnable = target;
String core = getCoreOfTask(ssb, task);
/* We'll update both the Core and Runnable attributes */
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core);
ssb.modifyAttribute(ts, STATE_SUSPENDED.getValue().unboxValue(), quark);
quark = ssb.getQuarkRelativeAndAdd(quark, runnable);
ssb.modifyAttribute(ts, STATE_SUSPENDED.getValue().unboxValue(), quark);
}
break;
case "terminate": //$NON-NLS-1$
updateTaskStateSystem(ssb, ts, event, STATE_TASK_TERMINATED);
if (source.startsWith(ENTITY_CORE)) {
String core = source;
task = target;
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core);
ssb.modifyAttribute(ts, STATE_NOT_RUNNING.getValue().unboxValue(), quark);
/* Remove our "active task on core" bookmark */
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, ATTRIBUTE_ACTIVE_CORE);
ITmfStateValue value = TmfStateValue.nullValue();
ssb.modifyAttribute(ts, value.unboxValue(), quark);
/* Mark the Cores/* attribute as not running */
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_CORES, core);
ssb.modifyAttribute(ts, STATE_CORE_IDLE.getValue().unboxValue(), quark);
} else if (source.startsWith(ENTITY_TASK)) {
task = source;
String runnable = target;
String core = getCoreOfTask(ssb, task);
quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core, runnable);
ssb.modifyAttribute(ts, STATE_NOT_RUNNING.getValue().unboxValue(), quark);
}
break;
case "preempt": //$NON-NLS-1$
case "release": //$NON-NLS-1$
case "release_parking": //$NON-NLS-1$
updateTaskStateSystem(ssb, ts, event, STATE_TASK_READY);
break;
case "wait": //$NON-NLS-1$
updateTaskStateSystem(ssb, ts, event, STATE_TASK_WAITING);
break;
case "park": //$NON-NLS-1$
updateTaskStateSystem(ssb, ts, event, STATE_TASK_PARKING);
break;
case "poll": //$NON-NLS-1$
//$FALL-THROUGH$
case "poll_parking": //$NON-NLS-1$
updateTaskStateSystem(ssb, ts, event, STATE_TASK_POLLING);
break;
case "run": //$NON-NLS-1$
updateTaskStateSystem(ssb, ts, event, STATE_TASK_RUNNING);
break;
default:
break;
}
} catch (AttributeNotFoundException e) {
throw new IllegalStateException(e);
}
}
private static void updateTaskStateSystem(
final ITmfStateSystemBuilder ssb,
final long ts, BtfEvent event,
TmfNamedStateValue stateValue)
throws AttributeNotFoundException {
String name = event.getName();
if (name.equals("Task")) { //$NON-NLS-1$
String task = event.getTarget();
int quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task);
ssb.modifyAttribute(ts, stateValue.getValue().unboxValue(), quark);
}
}
private static String getCoreOfTask(ITmfStateSystemBuilder ssb, String task) {
try {
int quark = ssb.getQuarkAbsolute(ATTRIBUTE_TASKS, task, ATTRIBUTE_ACTIVE_CORE);
ITmfStateValue value = ssb.queryOngoingState(quark);
return value.unboxStr();
} catch (AttributeNotFoundException e) {
throw new IllegalStateException(e);
}
}
}