1 /**********************************************************************
2 * Copyright (c) 2014, 2016 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
.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
;
34 import com
.google
.common
.collect
.ImmutableMap
;
37 * State provider to track the memory of the threads using the UST libc wrapper
40 * @author Matthew Khouzam
41 * @author Geneviève Bastien
43 public class UstMemoryStateProvider
extends AbstractTmfStateProvider
{
45 /* Version of this state provider */
46 private static final int VERSION
= 1;
48 private static final Long MINUS_ONE
= Long
.valueOf(-1);
49 private static final Long ZERO
= Long
.valueOf(0);
50 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
52 private static final int MALLOC_INDEX
= 1;
53 private static final int FREE_INDEX
= 2;
54 private static final int CALLOC_INDEX
= 3;
55 private static final int REALLOC_INDEX
= 4;
56 private static final int MEMALIGN_INDEX
= 5;
57 private static final int POSIX_MEMALIGN_INDEX
= 6;
59 /** Map of a pointer to a memory zone to the size of the memory */
60 private final Map
<Long
, Long
> fMemory
= new HashMap
<>();
62 private final @NonNull ILttngUstEventLayout fLayout
;
63 private final @NonNull Map
<String
, Integer
> fEventNames
;
71 public UstMemoryStateProvider(@NonNull LttngUstTrace trace
) {
72 super(trace
, "Ust:Memory"); //$NON-NLS-1$
73 fLayout
= trace
.getEventLayout();
74 fEventNames
= buildEventNames(fLayout
);
77 private static @NonNull Map
<String
, Integer
> buildEventNames(ILttngUstEventLayout layout
) {
78 ImmutableMap
.Builder
<String
, Integer
> builder
= ImmutableMap
.builder();
79 builder
.put(layout
.eventLibcMalloc(), MALLOC_INDEX
);
80 builder
.put(layout
.eventLibcFree(), FREE_INDEX
);
81 builder
.put(layout
.eventLibcCalloc(), CALLOC_INDEX
);
82 builder
.put(layout
.eventLibcRealloc(), REALLOC_INDEX
);
83 builder
.put(layout
.eventLibcMemalign(), MEMALIGN_INDEX
);
84 builder
.put(layout
.eventLibcPosixMemalign(), POSIX_MEMALIGN_INDEX
);
85 return builder
.build();
89 protected void eventHandle(ITmfEvent event
) {
90 String name
= event
.getName();
91 Integer index
= fEventNames
.get(name
);
92 int intIndex
= (index
== null ?
-1 : index
.intValue());
96 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
97 if (ZERO
.equals(ptr
)) {
100 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
101 setMem(event
, ptr
, size
);
105 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
106 if (ZERO
.equals(ptr
)) {
109 setMem(event
, ptr
, ZERO
);
113 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
114 if (ZERO
.equals(ptr
)) {
117 Long nmemb
= (Long
) event
.getContent().getField(fLayout
.fieldNmemb()).getValue();
118 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
119 setMem(event
, ptr
, size
* nmemb
);
122 case REALLOC_INDEX
: {
123 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
124 if (ZERO
.equals(ptr
)) {
127 Long newPtr
= (Long
) event
.getContent().getField(fLayout
.fieldInPtr()).getValue();
128 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
129 setMem(event
, ptr
, ZERO
);
130 setMem(event
, newPtr
, size
);
133 case MEMALIGN_INDEX
: {
134 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldPtr()).getValue();
135 if (ZERO
.equals(ptr
)) {
138 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
139 setMem(event
, ptr
, size
);
142 case POSIX_MEMALIGN_INDEX
: {
143 Long ptr
= (Long
) event
.getContent().getField(fLayout
.fieldOutPtr()).getValue();
144 if (ZERO
.equals(ptr
)) {
147 Long size
= (Long
) event
.getContent().getField(fLayout
.fieldSize()).getValue();
148 setMem(event
, ptr
, size
);
152 /* Ignore other event types */
159 public ITmfStateProvider
getNewInstance() {
160 return new UstMemoryStateProvider(getTrace());
164 public LttngUstTrace
getTrace() {
165 return (LttngUstTrace
) super.getTrace();
169 public int getVersion() {
173 private Long
getVtid(ITmfEvent event
) {
174 ITmfEventField field
= event
.getContent().getField(fLayout
.contextVtid());
178 return (Long
) field
.getValue();
181 private String
getProcname(ITmfEvent event
) {
182 ITmfEventField field
= event
.getContent().getField(fLayout
.contextProcname());
186 return (String
) field
.getValue();
189 private void setMem(ITmfEvent event
, Long ptr
, Long size
) {
190 ITmfStateSystemBuilder ss
= checkNotNull(getStateSystemBuilder());
191 long ts
= event
.getTimestamp().getValue();
192 Long tid
= getVtid(event
);
194 Long memoryDiff
= size
;
195 /* Size is 0, it means it was deleted */
196 if (ZERO
.equals(size
)) {
197 Long memSize
= fMemory
.remove(ptr
);
198 if (memSize
== null) {
201 memoryDiff
= -memSize
;
203 fMemory
.put(ptr
, size
);
206 int tidQuark
= ss
.getQuarkAbsoluteAndAdd(tid
.toString());
207 int tidMemQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_MEMORY_ATTRIBUTE
);
209 ITmfStateValue prevMem
= ss
.queryOngoingState(tidMemQuark
);
210 /* First time we set this value */
211 if (prevMem
.isNull()) {
212 int procNameQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_PROCNAME_ATTRIBUTE
);
213 String procName
= getProcname(event
);
215 * No tid/procname for the event for the event, added to a
218 if (tid
.equals(MINUS_ONE
)) {
219 procName
= UstMemoryStrings
.OTHERS
;
221 ss
.modifyAttribute(ts
, TmfStateValue
.newValueString(procName
), procNameQuark
);
222 prevMem
= TmfStateValue
.newValueLong(0);
225 long prevMemValue
= prevMem
.unboxLong();
226 prevMemValue
+= memoryDiff
.longValue();
227 ss
.modifyAttribute(ts
, TmfStateValue
.newValueLong(prevMemValue
), tidMemQuark
);
228 } catch (TimeRangeException
| StateValueTypeException e
) {
229 throw new IllegalStateException(e
);