LTTng: Add a virtual CPU view for the virtual machine analysis
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.kernel.ui / src / org / eclipse / tracecompass / internal / lttng2 / kernel / ui / views / vm / vcpuview / VirtualMachinePresentationProvider.java
CommitLineData
b1a7aebb
MG
1/*******************************************************************************
2 * Copyright (c) 2016 École Polytechnique de Montréal
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
10package org.eclipse.tracecompass.internal.lttng2.kernel.ui.views.vm.vcpuview;
11
12import org.eclipse.jdt.annotation.Nullable;
13import org.eclipse.swt.SWT;
14import org.eclipse.swt.graphics.Color;
15import org.eclipse.swt.graphics.GC;
16import org.eclipse.swt.graphics.RGB;
17import org.eclipse.swt.graphics.Rectangle;
18import org.eclipse.swt.widgets.Display;
19import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.StateValues;
20import org.eclipse.tracecompass.internal.lttng2.kernel.core.analysis.vm.VcpuStateValues;
21import org.eclipse.tracecompass.internal.lttng2.kernel.ui.views.vm.vcpuview.VirtualMachineCommon.Type;
22import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.StateItem;
23import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
24import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
25import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
26import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
27
28/**
29 * Presentation provider for the Virtual Machine view, based on the generic TMF
30 * presentation provider.
31 *
32 * @author Mohamad Gebai
33 */
34public class VirtualMachinePresentationProvider extends TimeGraphPresentationProvider {
35
36 /*
37 * TODO: Some of it is copy-pasted from the control flow presentation
38 * provider because it actually is the same data as from the control flow
39 * view. Ideally, we should reuse what is there instead of rewriting it here
40 */
41 private enum State {
42 UNKNOWN(new RGB(100, 100, 100)),
43 IDLE(new RGB(200, 200, 200)),
44 USERMODE(new RGB(0, 200, 0)),
45 WAIT_VMM(new RGB(200, 0, 0)),
46 VCPU_PREEMPTED(new RGB(120, 40, 90)),
47 THREAD_UNKNOWN(new RGB(100, 100, 100)),
48 THREAD_WAIT_BLOCKED(new RGB(200, 200, 0)),
49 THREAD_WAIT_FOR_CPU(new RGB(200, 100, 0)),
50 THREAD_USERMODE(new RGB(0, 200, 0)),
51 THREAD_SYSCALL(new RGB(0, 0, 200)),
52 THREAD_INTERRUPTED(new RGB(200, 0, 100));
53
54 public final RGB rgb;
55
56 private State(RGB rgb) {
57 this.rgb = rgb;
58 }
59 }
60
61 /**
62 * Default constructor
63 */
64 public VirtualMachinePresentationProvider() {
65 super();
66 }
67
68 private static State[] getStateValues() {
69 return State.values();
70 }
71
72 private static State getStateForVcpu(int value) {
73 if ((value & VcpuStateValues.VCPU_PREEMPT) > 0) {
74 return State.VCPU_PREEMPTED;
75 } else if ((value & VcpuStateValues.VCPU_VMM) > 0) {
76 return State.WAIT_VMM;
77 } else if (value == 2) {
78 return State.USERMODE;
79 } else if (value == 1) {
80 return State.IDLE;
81 } else {
82 return State.UNKNOWN;
83 }
84 }
85
86 private static @Nullable State getStateForThread(int value) {
87 if (value == VcpuStateValues.VCPU_PREEMPT) {
88 return null;
89 }
90 switch (value) {
91 case StateValues.PROCESS_STATUS_RUN_USERMODE:
92 return State.THREAD_USERMODE;
93 case StateValues.PROCESS_STATUS_RUN_SYSCALL:
94 return State.THREAD_SYSCALL;
95 case StateValues.PROCESS_STATUS_WAIT_FOR_CPU:
96 return State.THREAD_WAIT_FOR_CPU;
97 case StateValues.PROCESS_STATUS_WAIT_BLOCKED:
98 return State.THREAD_WAIT_BLOCKED;
99 case StateValues.PROCESS_STATUS_INTERRUPTED:
100 return State.THREAD_INTERRUPTED;
101 case StateValues.PROCESS_STATUS_UNKNOWN:
102 case StateValues.PROCESS_STATUS_WAIT_UNKNOWN:
103 return State.THREAD_UNKNOWN;
104 default:
105 return null;
106 }
107 }
108
109 private static @Nullable State getEventState(TimeEvent event) {
110 if (event.hasValue()) {
111 VirtualMachineViewEntry entry = (VirtualMachineViewEntry) event.getEntry();
112 int value = event.getValue();
113
114 if (entry.getType() == Type.VCPU) {
115 return getStateForVcpu(value);
116 } else if (entry.getType() == Type.THREAD) {
117 return getStateForThread(value);
118 }
119 }
120 return null;
121 }
122
123 @Override
124 public int getStateTableIndex(@Nullable ITimeEvent event) {
125 if (event == null) {
126 return TRANSPARENT;
127 }
128 State state = getEventState((TimeEvent) event);
129 if (state != null) {
130 return state.ordinal();
131 }
132 if (event instanceof NullTimeEvent) {
133 return INVISIBLE;
134 }
135 return TRANSPARENT;
136 }
137
138 @Override
139 public StateItem[] getStateTable() {
140 State[] states = getStateValues();
141 StateItem[] stateTable = new StateItem[states.length];
142 for (int i = 0; i < stateTable.length; i++) {
143 State state = states[i];
144 stateTable[i] = new StateItem(state.rgb, state.toString());
145 }
146 return stateTable;
147 }
148
149 @Override
150 public @Nullable String getEventName(@Nullable ITimeEvent event) {
151 if (event == null) {
152 return null;
153 }
154 State state = getEventState((TimeEvent) event);
155 if (state != null) {
156 return state.toString();
157 }
158 if (event instanceof NullTimeEvent) {
159 return null;
160 }
161 return Messages.VmView_multipleStates;
162 }
163
164 @Override
165 public void postDrawEvent(@Nullable ITimeEvent event, @Nullable Rectangle bounds, @Nullable GC gc) {
166 if (bounds == null || gc == null) {
167 return;
168 }
169 boolean visible = bounds.width == 0 ? false : true;
170 if (!visible) {
171 return;
172 }
173 if (!(event instanceof TimeEvent)) {
174 return;
175 }
176 TimeEvent ev = (TimeEvent) event;
177 /*
178 * FIXME: There seems to be a bug when multiple events should be drawn
179 * under a alpha event. See FIXME comment in
180 * VirtualMachineView#getEventList
181 */
182 if (ev.hasValue()) {
183 VirtualMachineViewEntry entry = (VirtualMachineViewEntry) event.getEntry();
184
185 if (entry.getType() == Type.THREAD) {
186 int value = ev.getValue();
187 if ((value & VcpuStateValues.VCPU_PREEMPT) != 0) {
188 /*
189 * If the status was preempted at this time, draw an alpha
190 * over this state
191 */
192 Color alphaColor = Display.getDefault().getSystemColor(SWT.COLOR_RED);
193
194 int alpha = gc.getAlpha();
195 Color background = gc.getBackground();
196 // fill all rect area
197 gc.setBackground(alphaColor);
198 gc.setAlpha(70);
199 gc.fillRectangle(bounds);
200
201 gc.setBackground(background);
202 gc.setAlpha(alpha);
203 }
204 }
205 }
206 }
207
208}
This page took 0.034481 seconds and 5 git commands to generate.