1 /**********************************************************************
2 * Copyright (c) 2014, 2015 Ericsson, École Polytechnique de Montréal
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
10 * Matthew Khouzam - Initial API and implementation
11 * Geneviève Bastien - Memory is per thread and only total is kept
12 **********************************************************************/
14 package org
.eclipse
.tracecompass
.internal
.lttng2
.ust
.core
.analysis
.memory
;
16 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
18 import java
.util
.HashMap
;
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
.AttributeNotFoundException
;
26 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
27 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
28 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
29 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
30 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
31 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.AbstractTmfStateProvider
;
33 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.ITmfStateProvider
;
35 import com
.google
.common
.collect
.ImmutableMap
;
38 * State provider to track the memory of the threads using the UST libc wrapper
41 * @author Matthew Khouzam
42 * @author Geneviève Bastien
44 public class UstMemoryStateProvider
extends AbstractTmfStateProvider
{
46 /* Version of this state provider */
47 private static final int VERSION
= 1;
49 private static final Long MINUS_ONE
= Long
.valueOf(-1);
50 private static final Long ZERO
= Long
.valueOf(0);
51 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
53 private static final int MALLOC_INDEX
= 1;
54 private static final int FREE_INDEX
= 2;
55 private static final int CALLOC_INDEX
= 3;
56 private static final int REALLOC_INDEX
= 4;
57 private static final int MEMALIGN_INDEX
= 5;
58 private static final int POSIX_MEMALIGN_INDEX
= 6;
60 /** Map of a pointer to a memory zone to the size of the memory */
61 private final Map
<Long
, Long
> fMemory
= new HashMap
<>();
63 private final @NonNull ILttngUstEventLayout fLayout
;
64 private final @NonNull Map
<String
, Integer
> fEventNames
;
72 public UstMemoryStateProvider(@NonNull LttngUstTrace trace
) {
73 super(trace
, "Ust:Memory"); //$NON-NLS-1$
74 fLayout
= trace
.getEventLayout();
75 fEventNames
= buildEventNames(fLayout
);
78 private static @NonNull Map
<String
, Integer
> buildEventNames(ILttngUstEventLayout layout
) {
79 ImmutableMap
.Builder
<String
, Integer
> builder
= ImmutableMap
.builder();
80 builder
.put(layout
.eventLibcMalloc(), MALLOC_INDEX
);
81 builder
.put(layout
.eventLibcFree(), FREE_INDEX
);
82 builder
.put(layout
.eventLibcCalloc(), CALLOC_INDEX
);
83 builder
.put(layout
.eventLibcRealloc(), REALLOC_INDEX
);
84 builder
.put(layout
.eventLibcMemalign(), MEMALIGN_INDEX
);
85 builder
.put(layout
.eventLibcPosixMemalign(), POSIX_MEMALIGN_INDEX
);
86 return builder
.build();
90 protected void eventHandle(ITmfEvent event
) {
91 String name
= event
.getName();
92 Integer index
= fEventNames
.get(name
);
93 int intIndex
= (index
== null ?
-1 : index
.intValue());
97 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
98 if (ZERO
.equals(ptr
)) {
101 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
102 setMem(event
, ptr
, size
);
106 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
107 if (ZERO
.equals(ptr
)) {
110 setMem(event
, ptr
, ZERO
);
114 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
115 if (ZERO
.equals(ptr
)) {
118 Long nmemb
= (Long
) event
.getContent().getField(fLayout
.fieldNmemb()).getValue();
119 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
120 setMem(event
, ptr
, size
* nmemb
);
123 case REALLOC_INDEX
: {
124 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
125 if (ZERO
.equals(ptr
)) {
128 Long newPtr
= (Long
) event
.getContent().getField(fLayout
.fieldInPtr()).getValue();
129 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
130 setMem(event
, ptr
, ZERO
);
131 setMem(event
, newPtr
, size
);
134 case MEMALIGN_INDEX
: {
135 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
136 if (ZERO
.equals(ptr
)) {
139 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
140 setMem(event
, ptr
, size
);
143 case POSIX_MEMALIGN_INDEX
: {
144 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldOutPtr()).getValue();
145 if (ZERO
.equals(ptr
)) {
148 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
149 setMem(event
, ptr
, size
);
153 /* Ignore other event types */
160 public ITmfStateProvider
getNewInstance() {
161 return new UstMemoryStateProvider(getTrace());
165 public LttngUstTrace
getTrace() {
166 return (LttngUstTrace
) super.getTrace();
170 public int getVersion() {
174 private Long
getVtid(ITmfEvent event
) {
175 ITmfEventField field
= event
.getContent().getField(fLayout
.contextVtid());
179 return (Long
) field
.getValue();
182 private String
getProcname(ITmfEvent event
) {
183 ITmfEventField field
= event
.getContent().getField(fLayout
.contextProcname());
187 return (String
) field
.getValue();
190 private void setMem(ITmfEvent event
, Long ptr
, Long size
) {
191 ITmfStateSystemBuilder ss
= checkNotNull(getStateSystemBuilder());
192 long ts
= event
.getTimestamp().getValue();
193 Long tid
= getVtid(event
);
195 Long memoryDiff
= size
;
196 /* Size is 0, it means it was deleted */
197 if (ZERO
.equals(size
)) {
198 Long memSize
= fMemory
.remove(ptr
);
199 if (memSize
== null) {
202 memoryDiff
= -memSize
;
204 fMemory
.put(ptr
, size
);
207 int tidQuark
= ss
.getQuarkAbsoluteAndAdd(tid
.toString());
208 int tidMemQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_MEMORY_ATTRIBUTE
);
210 ITmfStateValue prevMem
= ss
.queryOngoingState(tidMemQuark
);
211 /* First time we set this value */
212 if (prevMem
.isNull()) {
213 int procNameQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_PROCNAME_ATTRIBUTE
);
214 String procName
= getProcname(event
);
216 * No tid/procname for the event for the event, added to a
219 if (tid
.equals(MINUS_ONE
)) {
220 procName
= UstMemoryStrings
.OTHERS
;
222 ss
.modifyAttribute(ts
, TmfStateValue
.newValueString(procName
), procNameQuark
);
223 prevMem
= TmfStateValue
.newValueLong(0);
226 long prevMemValue
= prevMem
.unboxLong();
227 prevMemValue
+= memoryDiff
.longValue();
228 ss
.modifyAttribute(ts
, TmfStateValue
.newValueLong(prevMemValue
), tidMemQuark
);
229 } catch (AttributeNotFoundException
| TimeRangeException
| StateValueTypeException e
) {
230 throw new IllegalStateException(e
);