ust: Add a LinuxTidAspect using the context._vtid
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.ust.core / src / org / eclipse / tracecompass / internal / lttng2 / ust / core / analysis / memory / UstMemoryStateProvider.java
CommitLineData
2237fe8a 1/**********************************************************************
ed48dc75 2 * Copyright (c) 2014, 2016 Ericsson, École Polytechnique de Montréal
2237fe8a
GB
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 * Matthew Khouzam - Initial API and implementation
11 * Geneviève Bastien - Memory is per thread and only total is kept
12 **********************************************************************/
13
116738ad 14package org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.memory;
2237fe8a 15
d0c7e4ba
AM
16import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
17
2237fe8a
GB
18import java.util.HashMap;
19import java.util.Map;
20
d0c7e4ba 21import org.eclipse.jdt.annotation.NonNull;
d6e6f5d5 22import org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.LinuxTidAspect;
9bc60be7 23import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace;
7e452c97 24import org.eclipse.tracecompass.lttng2.ust.core.trace.layout.ILttngUstEventLayout;
d0c7e4ba 25import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
e894a508
AM
26import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
27import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
28import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
29import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
2bdf0193
AM
30import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
31import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
32import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
33import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
d6e6f5d5 34import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
2237fe8a 35
7e452c97
AM
36import com.google.common.collect.ImmutableMap;
37
2237fe8a
GB
38/**
39 * State provider to track the memory of the threads using the UST libc wrapper
40 * memory events.
41 *
e4ba10ee
LPD
42 * Attribute tree:
43 *
44 * <pre>
45 * |- <TID number>
46 * | |- UST_MEMORY_MEMORY_ATTRIBUTE -> Memory Usage
47 * | |- UST_MEMORY_PROCNAME_ATTRIBUTE -> Process name
48 * </pre>
49 *
2237fe8a
GB
50 * @author Matthew Khouzam
51 * @author Geneviève Bastien
52 */
116738ad 53public class UstMemoryStateProvider extends AbstractTmfStateProvider {
2237fe8a
GB
54
55 /* Version of this state provider */
56 private static final int VERSION = 1;
57
2237fe8a
GB
58 private static final Long MINUS_ONE = Long.valueOf(-1);
59 private static final Long ZERO = Long.valueOf(0);
60 private static final String EMPTY_STRING = ""; //$NON-NLS-1$
61
7e452c97
AM
62 private static final int MALLOC_INDEX = 1;
63 private static final int FREE_INDEX = 2;
64 private static final int CALLOC_INDEX = 3;
65 private static final int REALLOC_INDEX = 4;
66 private static final int MEMALIGN_INDEX = 5;
67 private static final int POSIX_MEMALIGN_INDEX = 6;
68
69 /** Map of a pointer to a memory zone to the size of the memory */
70 private final Map<Long, Long> fMemory = new HashMap<>();
71
72 private final @NonNull ILttngUstEventLayout fLayout;
73 private final @NonNull Map<String, Integer> fEventNames;
74
2237fe8a
GB
75 /**
76 * Constructor
77 *
78 * @param trace
79 * trace
80 */
116738ad 81 public UstMemoryStateProvider(@NonNull LttngUstTrace trace) {
e2bcc8a5 82 super(trace, "Ust:Memory"); //$NON-NLS-1$
7e452c97
AM
83 fLayout = trace.getEventLayout();
84 fEventNames = buildEventNames(fLayout);
85 }
86
87 private static @NonNull Map<String, Integer> buildEventNames(ILttngUstEventLayout layout) {
88 ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
89 builder.put(layout.eventLibcMalloc(), MALLOC_INDEX);
90 builder.put(layout.eventLibcFree(), FREE_INDEX);
91 builder.put(layout.eventLibcCalloc(), CALLOC_INDEX);
92 builder.put(layout.eventLibcRealloc(), REALLOC_INDEX);
93 builder.put(layout.eventLibcMemalign(), MEMALIGN_INDEX);
94 builder.put(layout.eventLibcPosixMemalign(), POSIX_MEMALIGN_INDEX);
0e4f957e 95 return builder.build();
2237fe8a
GB
96 }
97
98 @Override
99 protected void eventHandle(ITmfEvent event) {
578716e6 100 String name = event.getName();
7e452c97
AM
101 Integer index = fEventNames.get(name);
102 int intIndex = (index == null ? -1 : index.intValue());
103
104 switch (intIndex) {
105 case MALLOC_INDEX: {
106 Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
2237fe8a
GB
107 if (ZERO.equals(ptr)) {
108 return;
109 }
7e452c97 110 Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
2237fe8a
GB
111 setMem(event, ptr, size);
112 }
113 break;
7e452c97
AM
114 case FREE_INDEX: {
115 Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
2237fe8a
GB
116 if (ZERO.equals(ptr)) {
117 return;
118 }
119 setMem(event, ptr, ZERO);
120 }
121 break;
7e452c97
AM
122 case CALLOC_INDEX: {
123 Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
2237fe8a
GB
124 if (ZERO.equals(ptr)) {
125 return;
126 }
7e452c97
AM
127 Long nmemb = (Long) event.getContent().getField(fLayout.fieldNmemb()).getValue();
128 Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
2237fe8a
GB
129 setMem(event, ptr, size * nmemb);
130 }
131 break;
7e452c97
AM
132 case REALLOC_INDEX: {
133 Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
2237fe8a
GB
134 if (ZERO.equals(ptr)) {
135 return;
136 }
7e452c97
AM
137 Long newPtr = (Long) event.getContent().getField(fLayout.fieldInPtr()).getValue();
138 Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
2237fe8a
GB
139 setMem(event, ptr, ZERO);
140 setMem(event, newPtr, size);
141 }
142 break;
7e452c97
AM
143 case MEMALIGN_INDEX: {
144 Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
2237fe8a
GB
145 if (ZERO.equals(ptr)) {
146 return;
147 }
7e452c97 148 Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
2237fe8a
GB
149 setMem(event, ptr, size);
150 }
151 break;
7e452c97
AM
152 case POSIX_MEMALIGN_INDEX: {
153 Long ptr = (Long) event.getContent().getField(fLayout.fieldOutPtr()).getValue();
2237fe8a
GB
154 if (ZERO.equals(ptr)) {
155 return;
156 }
7e452c97 157 Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
2237fe8a
GB
158 setMem(event, ptr, size);
159 }
160 break;
161 default:
7e452c97 162 /* Ignore other event types */
2237fe8a
GB
163 break;
164 }
165
166 }
167
168 @Override
169 public ITmfStateProvider getNewInstance() {
116738ad 170 return new UstMemoryStateProvider(getTrace());
2237fe8a
GB
171 }
172
173 @Override
174 public LttngUstTrace getTrace() {
175 return (LttngUstTrace) super.getTrace();
176 }
177
178 @Override
179 public int getVersion() {
180 return VERSION;
181 }
182
d6e6f5d5
GB
183 private static Long getVtid(ITmfEvent event) {
184 /* We checked earlier that the "vtid" context is present */
185 Integer tid = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), LinuxTidAspect.class, event);
186 if (tid == null) {
2237fe8a
GB
187 return MINUS_ONE;
188 }
d6e6f5d5 189 return tid.longValue();
2237fe8a
GB
190 }
191
7e452c97
AM
192 private String getProcname(ITmfEvent event) {
193 ITmfEventField field = event.getContent().getField(fLayout.contextProcname());
2237fe8a
GB
194 if (field == null) {
195 return EMPTY_STRING;
196 }
197 return (String) field.getValue();
198 }
199
200 private void setMem(ITmfEvent event, Long ptr, Long size) {
d0c7e4ba 201 ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
ac8c4e6b 202 long ts = event.getTimestamp().toNanos();
2237fe8a
GB
203 Long tid = getVtid(event);
204
205 Long memoryDiff = size;
206 /* Size is 0, it means it was deleted */
207 if (ZERO.equals(size)) {
208 Long memSize = fMemory.remove(ptr);
209 if (memSize == null) {
210 return;
211 }
212 memoryDiff = -memSize;
213 } else {
214 fMemory.put(ptr, size);
215 }
216 try {
217 int tidQuark = ss.getQuarkAbsoluteAndAdd(tid.toString());
218 int tidMemQuark = ss.getQuarkRelativeAndAdd(tidQuark, UstMemoryStrings.UST_MEMORY_MEMORY_ATTRIBUTE);
219
220 ITmfStateValue prevMem = ss.queryOngoingState(tidMemQuark);
221 /* First time we set this value */
222 if (prevMem.isNull()) {
223 int procNameQuark = ss.getQuarkRelativeAndAdd(tidQuark, UstMemoryStrings.UST_MEMORY_PROCNAME_ATTRIBUTE);
224 String procName = getProcname(event);
225 /*
226 * No tid/procname for the event for the event, added to a
227 * 'others' thread
228 */
229 if (tid.equals(MINUS_ONE)) {
230 procName = UstMemoryStrings.OTHERS;
231 }
232 ss.modifyAttribute(ts, TmfStateValue.newValueString(procName), procNameQuark);
233 prevMem = TmfStateValue.newValueLong(0);
234 }
235
236 long prevMemValue = prevMem.unboxLong();
237 prevMemValue += memoryDiff.longValue();
238 ss.modifyAttribute(ts, TmfStateValue.newValueLong(prevMemValue), tidMemQuark);
ed48dc75 239 } catch (TimeRangeException | StateValueTypeException e) {
2237fe8a
GB
240 throw new IllegalStateException(e);
241 }
242 }
243
244}
This page took 0.085567 seconds and 5 git commands to generate.