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