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
.statesystem
.core
.ITmfStateSystemBuilder
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
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
;
35 * State provider to track the memory of the threads using the UST libc wrapper
38 * @author Matthew Khouzam
39 * @author Geneviève Bastien
41 public class UstMemoryStateProvider
extends AbstractTmfStateProvider
{
43 /* Version of this state provider */
44 private static final int VERSION
= 1;
46 /* Maps a pointer to a memory zone to the size of the memory */
47 private final Map
<Long
, Long
> fMemory
= new HashMap
<>();
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$
59 public UstMemoryStateProvider(@NonNull LttngUstTrace trace
) {
60 super(trace
, "Ust:Memory"); //$NON-NLS-1$
64 protected void eventHandle(ITmfEvent event
) {
65 String name
= event
.getName();
67 case UstMemoryStrings
.MALLOC
: {
68 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
69 if (ZERO
.equals(ptr
)) {
72 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
73 setMem(event
, ptr
, size
);
76 case UstMemoryStrings
.FREE
: {
77 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
78 if (ZERO
.equals(ptr
)) {
81 setMem(event
, ptr
, ZERO
);
84 case UstMemoryStrings
.CALLOC
: {
85 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
86 if (ZERO
.equals(ptr
)) {
89 Long nmemb
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_NMEMB
).getValue();
90 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
91 setMem(event
, ptr
, size
* nmemb
);
94 case UstMemoryStrings
.REALLOC
: {
95 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
96 if (ZERO
.equals(ptr
)) {
99 Long newPtr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_INPTR
).getValue();
100 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
101 setMem(event
, ptr
, ZERO
);
102 setMem(event
, newPtr
, size
);
105 case UstMemoryStrings
.MEMALIGN
: {
106 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
107 if (ZERO
.equals(ptr
)) {
110 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
111 setMem(event
, ptr
, size
);
114 case UstMemoryStrings
.POSIX_MEMALIGN
: {
115 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_OUTPTR
).getValue();
116 if (ZERO
.equals(ptr
)) {
119 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
120 setMem(event
, ptr
, size
);
130 public ITmfStateProvider
getNewInstance() {
131 return new UstMemoryStateProvider(getTrace());
135 public LttngUstTrace
getTrace() {
136 return (LttngUstTrace
) super.getTrace();
140 public int getVersion() {
144 private static Long
getVtid(ITmfEvent event
) {
145 ITmfEventField field
= event
.getContent().getField(UstMemoryStrings
.CONTEXT_VTID
);
149 return (Long
) field
.getValue();
152 private static String
getProcname(ITmfEvent event
) {
153 ITmfEventField field
= event
.getContent().getField(UstMemoryStrings
.CONTEXT_PROCNAME
);
157 return (String
) field
.getValue();
160 private void setMem(ITmfEvent event
, Long ptr
, Long size
) {
161 ITmfStateSystemBuilder ss
= checkNotNull(getStateSystemBuilder());
162 long ts
= event
.getTimestamp().getValue();
163 Long tid
= getVtid(event
);
165 Long memoryDiff
= size
;
166 /* Size is 0, it means it was deleted */
167 if (ZERO
.equals(size
)) {
168 Long memSize
= fMemory
.remove(ptr
);
169 if (memSize
== null) {
172 memoryDiff
= -memSize
;
174 fMemory
.put(ptr
, size
);
177 int tidQuark
= ss
.getQuarkAbsoluteAndAdd(tid
.toString());
178 int tidMemQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_MEMORY_ATTRIBUTE
);
180 ITmfStateValue prevMem
= ss
.queryOngoingState(tidMemQuark
);
181 /* First time we set this value */
182 if (prevMem
.isNull()) {
183 int procNameQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_PROCNAME_ATTRIBUTE
);
184 String procName
= getProcname(event
);
186 * No tid/procname for the event for the event, added to a
189 if (tid
.equals(MINUS_ONE
)) {
190 procName
= UstMemoryStrings
.OTHERS
;
192 ss
.modifyAttribute(ts
, TmfStateValue
.newValueString(procName
), procNameQuark
);
193 prevMem
= TmfStateValue
.newValueLong(0);
196 long prevMemValue
= prevMem
.unboxLong();
197 prevMemValue
+= memoryDiff
.longValue();
198 ss
.modifyAttribute(ts
, TmfStateValue
.newValueLong(prevMemValue
), tidMemQuark
);
199 } catch (AttributeNotFoundException
| TimeRangeException
| StateValueTypeException e
) {
200 throw new IllegalStateException(e
);