Commit | Line | Data |
---|---|---|
ff71e543 MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2014 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Alexandre Montplaisir - Initial API and implementation | |
11 | * Matthew Khouzam - Add the task state system from figure 3 from the spec | |
12 | *******************************************************************************/ | |
13 | ||
14 | package org.eclipse.linuxtools.btf.core.analysis; | |
15 | ||
16 | import org.eclipse.linuxtools.btf.core.event.BtfEvent; | |
17 | import org.eclipse.linuxtools.btf.core.trace.BtfColumnNames; | |
18 | import org.eclipse.linuxtools.btf.core.trace.BtfTrace; | |
e894a508 AM |
19 | import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; |
20 | import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; | |
21 | import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; | |
22 | import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; | |
2bdf0193 AM |
23 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
24 | import org.eclipse.tracecompass.tmf.core.event.TmfEvent; | |
25 | import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; | |
26 | import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; | |
ff71e543 MK |
27 | |
28 | /** | |
29 | * State provider for the default BTF analysis. | |
30 | * | |
31 | * The generated attribute tree will look like this: | |
32 | * | |
33 | * <pre> | |
34 | * {root} | |
35 | * +- Cores | |
36 | * | +- Core 1 (not running/Name of the running Task) | |
37 | * | +- Core 2 (not running/Name of the running Task) | |
38 | * | | |
39 | * +- Tasks | |
40 | * +- Task A | |
41 | * | +- Core 1 (not running/running/suspended) | |
42 | * | | +- Runnable A1 (not running/running/suspended) | |
43 | * | | +- Runnable A2 (not running/running/suspended) | |
44 | * | +- Core 2 | |
45 | * | | +- Runnable A1 | |
46 | * | | +- Runnable A2 | |
47 | * | +- ActiveCore | |
48 | * | | |
49 | * +- Task B | |
50 | * +- Core 1 | |
51 | * | +- Runnable B1 | |
52 | * | +- Runnable B2 | |
53 | * +- Core 2 | |
54 | * | +- Runnable B1 | |
55 | * | +- Runnable B2 | |
56 | * +- ActiveCore | |
57 | * </pre> | |
58 | * | |
59 | * @author Alexandre Montplaisir | |
60 | */ | |
61 | public class BtfStateProvider extends AbstractTmfStateProvider { | |
62 | ||
63 | private static final int PROVIDER_VERSION = 3; | |
64 | ||
65 | private static class TmfNamedStateValue { | |
66 | private final String fName; | |
67 | private final TmfStateValue fValue; | |
68 | ||
69 | public TmfNamedStateValue(TmfStateValue value, String name) { | |
70 | fValue = value; | |
71 | fName = name; | |
72 | } | |
73 | ||
74 | public TmfStateValue getValue() { | |
75 | return fValue; | |
76 | } | |
77 | ||
78 | @Override | |
79 | public String toString() { | |
80 | return fName; | |
81 | } | |
82 | } | |
83 | ||
84 | private static final TmfNamedStateValue STATE_CORE_IDLE = new TmfNamedStateValue(TmfStateValue.newValueInt(0), "Idle"); //$NON-NLS-1$ | |
85 | ||
86 | private static final TmfNamedStateValue STATE_NOT_RUNNING = new TmfNamedStateValue(TmfStateValue.nullValue(), "Not Running"); //$NON-NLS-1$ | |
87 | private static final TmfNamedStateValue STATE_RUNNING = new TmfNamedStateValue(TmfStateValue.newValueInt((1)), "RUNNING"); //$NON-NLS-1$ | |
88 | private static final TmfNamedStateValue STATE_SUSPENDED = new TmfNamedStateValue(TmfStateValue.newValueInt((2)), "SUSPENDED"); //$NON-NLS-1$ | |
89 | ||
90 | private static final TmfNamedStateValue STATE_TASK_ACTIVE = new TmfNamedStateValue(TmfStateValue.newValueInt((4)), "Active"); //$NON-NLS-1$ | |
91 | private static final TmfNamedStateValue STATE_TASK_READY = new TmfNamedStateValue(TmfStateValue.newValueInt((5)), "Ready"); //$NON-NLS-1$ | |
92 | private static final TmfNamedStateValue STATE_TASK_RUNNING = new TmfNamedStateValue(TmfStateValue.newValueInt((6)), "Task Running"); //$NON-NLS-1$ | |
93 | private static final TmfNamedStateValue STATE_TASK_WAITING = new TmfNamedStateValue(TmfStateValue.newValueInt((7)), "Waiting"); //$NON-NLS-1$ | |
94 | private static final TmfNamedStateValue STATE_TASK_PARKING = new TmfNamedStateValue(TmfStateValue.newValueInt((8)), "Parking"); //$NON-NLS-1$ | |
95 | private static final TmfNamedStateValue STATE_TASK_POLLING = new TmfNamedStateValue(TmfStateValue.newValueInt((9)), "Polling"); //$NON-NLS-1$ | |
96 | private static final TmfNamedStateValue STATE_TASK_TERMINATED = new TmfNamedStateValue(TmfStateValue.nullValue(), "Terminated"); //$NON-NLS-1$ | |
97 | ||
98 | private static final String ENTITY_CORE = "Core"; //$NON-NLS-1$ | |
99 | private static final String ENTITY_TASK = "TASK"; //$NON-NLS-1$ | |
100 | // private static final String ENTITY_RUNNABLE = "RUNNABLE"; | |
101 | ||
102 | private static final String ATTRIBUTE_TASKS = "Tasks"; //$NON-NLS-1$ | |
103 | private static final String ATTRIBUTE_CORES = "Cores"; //$NON-NLS-1$ | |
104 | private static final String ATTRIBUTE_ACTIVE_CORE = "ActiveCore"; //$NON-NLS-1$ | |
105 | ||
106 | /** | |
107 | * Constructor | |
108 | * | |
109 | * @param trace | |
110 | * The trace for which we will be building this state system | |
111 | */ | |
112 | public BtfStateProvider(BtfTrace trace) { | |
113 | super(trace, TmfEvent.class, "Btf State Provider"); //$NON-NLS-1$ | |
114 | } | |
115 | ||
116 | @Override | |
117 | public BtfTrace getTrace() { | |
118 | return (BtfTrace) super.getTrace(); | |
119 | } | |
120 | ||
121 | @Override | |
122 | public int getVersion() { | |
123 | return PROVIDER_VERSION; | |
124 | } | |
125 | ||
126 | @Override | |
127 | public ITmfStateProvider getNewInstance() { | |
128 | return new BtfStateProvider(getTrace()); | |
129 | } | |
130 | ||
131 | @Override | |
132 | protected void eventHandle(ITmfEvent ev) { | |
133 | BtfEvent event = (BtfEvent) ev; | |
134 | final ITmfStateSystemBuilder ssb = this.ss; | |
135 | ||
136 | final long ts = event.getTimestamp().getValue(); | |
137 | final String eventType = (String) event.getContent().getField(BtfColumnNames.EVENT.toString()).getValue(); | |
138 | final String source = event.getSource(); | |
139 | final String target = event.getReference(); | |
140 | String task; | |
141 | int quark; | |
142 | try { | |
143 | switch (eventType) { | |
144 | ||
145 | case "activate": //$NON-NLS-1$ | |
146 | updateTaskStateSystem(ssb, ts, event, STATE_TASK_ACTIVE); | |
147 | break; | |
148 | ||
149 | case "start": //$NON-NLS-1$ | |
150 | case "resume": //$NON-NLS-1$ | |
151 | updateTaskStateSystem(ssb, ts, event, STATE_TASK_RUNNING); | |
152 | ||
153 | if (source.startsWith(ENTITY_CORE)) { | |
154 | String core = source; | |
155 | task = target; | |
156 | ||
157 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core); | |
158 | ssb.modifyAttribute(ts, STATE_RUNNING.getValue(), quark); | |
159 | ||
160 | /* Mark this task as active in the ActiveCore attribute */ | |
161 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, ATTRIBUTE_ACTIVE_CORE); | |
162 | ITmfStateValue value = TmfStateValue.newValueString(core); | |
163 | ssb.modifyAttribute(ts, value, quark); | |
164 | ||
165 | /* Mark this task as active in the Cores/* attribute */ | |
166 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_CORES, core); | |
167 | /* Until the view can display the string */ | |
168 | value = STATE_RUNNING.getValue(); | |
169 | ssb.modifyAttribute(ts, value, quark); | |
170 | ||
171 | } else if (source.startsWith(ENTITY_TASK)) { | |
172 | task = source; | |
173 | String runnable = target; | |
174 | String core = getCoreOfTask(ssb, task); | |
175 | ||
176 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core, runnable); | |
177 | ssb.modifyAttribute(ts, STATE_RUNNING.getValue(), quark); | |
178 | } | |
179 | break; | |
180 | ||
181 | case "suspend": //$NON-NLS-1$ | |
182 | /* "suspend" events only happen on Tasks */ | |
183 | if (source.startsWith(ENTITY_TASK)) { | |
184 | task = source; | |
185 | String runnable = target; | |
186 | String core = getCoreOfTask(ssb, task); | |
187 | ||
188 | /* We'll update both the Core and Runnable attributes */ | |
189 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core); | |
190 | ssb.modifyAttribute(ts, STATE_SUSPENDED.getValue(), quark); | |
191 | quark = ssb.getQuarkRelativeAndAdd(quark, runnable); | |
192 | ss.modifyAttribute(ts, STATE_SUSPENDED.getValue(), quark); | |
193 | } | |
194 | break; | |
195 | ||
196 | case "terminate": //$NON-NLS-1$ | |
197 | updateTaskStateSystem(ssb, ts, event, STATE_TASK_TERMINATED); | |
198 | ||
199 | if (source.startsWith(ENTITY_CORE)) { | |
200 | String core = source; | |
201 | task = target; | |
202 | ||
203 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core); | |
204 | ssb.modifyAttribute(ts, STATE_NOT_RUNNING.getValue(), quark); | |
205 | ||
206 | /* Remove our "active task on core" bookmark */ | |
207 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, ATTRIBUTE_ACTIVE_CORE); | |
208 | ITmfStateValue value = TmfStateValue.nullValue(); | |
209 | ssb.modifyAttribute(ts, value, quark); | |
210 | ||
211 | /* Mark the Cores/* attribute as not running */ | |
212 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_CORES, core); | |
213 | ssb.modifyAttribute(ts, STATE_CORE_IDLE.getValue(), quark); | |
214 | ||
215 | } else if (source.startsWith(ENTITY_TASK)) { | |
216 | task = source; | |
217 | String runnable = target; | |
218 | String core = getCoreOfTask(ssb, task); | |
219 | ||
220 | quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task, core, runnable); | |
221 | ssb.modifyAttribute(ts, STATE_NOT_RUNNING.getValue(), quark); | |
222 | } | |
223 | break; | |
224 | ||
225 | case "preempt": //$NON-NLS-1$ | |
226 | case "release": //$NON-NLS-1$ | |
227 | case "release_parking": //$NON-NLS-1$ | |
228 | updateTaskStateSystem(ssb, ts, event, STATE_TASK_READY); | |
229 | break; | |
230 | case "wait": //$NON-NLS-1$ | |
231 | updateTaskStateSystem(ssb, ts, event, STATE_TASK_WAITING); | |
232 | break; | |
233 | case "park": //$NON-NLS-1$ | |
234 | updateTaskStateSystem(ssb, ts, event, STATE_TASK_PARKING); | |
235 | break; | |
236 | case "poll": //$NON-NLS-1$ | |
237 | //$FALL-THROUGH$ | |
238 | case "poll_parking": //$NON-NLS-1$ | |
239 | updateTaskStateSystem(ssb, ts, event, STATE_TASK_POLLING); | |
240 | break; | |
241 | case "run": //$NON-NLS-1$ | |
242 | updateTaskStateSystem(ssb, ts, event, STATE_TASK_RUNNING); | |
243 | break; | |
244 | default: | |
245 | break; | |
246 | ||
247 | } | |
248 | } catch (AttributeNotFoundException e) { | |
249 | throw new IllegalStateException(e); | |
250 | } | |
251 | } | |
252 | ||
253 | private static void updateTaskStateSystem( | |
254 | final ITmfStateSystemBuilder ssb, | |
255 | final long ts, BtfEvent event, | |
256 | TmfNamedStateValue stateValue) | |
257 | throws AttributeNotFoundException { | |
258 | String name = event.getType().getName(); | |
259 | if (name.equals("Task")) { //$NON-NLS-1$ | |
260 | String task = event.getReference(); | |
261 | int quark = ssb.getQuarkAbsoluteAndAdd(ATTRIBUTE_TASKS, task); | |
262 | ssb.modifyAttribute(ts, stateValue.getValue(), quark); | |
263 | } | |
264 | } | |
265 | ||
266 | private static String getCoreOfTask(ITmfStateSystemBuilder ssb, String task) { | |
267 | try { | |
268 | int quark = ssb.getQuarkAbsolute(ATTRIBUTE_TASKS, task, ATTRIBUTE_ACTIVE_CORE); | |
269 | ITmfStateValue value = ssb.queryOngoingState(quark); | |
270 | return value.unboxStr(); | |
271 | } catch (AttributeNotFoundException e) { | |
272 | throw new IllegalStateException(e); | |
273 | } | |
274 | } | |
275 | } |