1 /**********************************************************************
2 * Copyright (c) 2014 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
.memoryusage
;
16 import java
.util
.HashMap
;
19 import org
.eclipse
.tracecompass
.lttng2
.ust
.core
.trace
.LttngUstTrace
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
27 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.AbstractTmfStateProvider
;
28 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.ITmfStateProvider
;
29 import org
.eclipse
.tracecompass
.tmf
.ctf
.core
.CtfTmfEvent
;
32 * State provider to track the memory of the threads using the UST libc wrapper
35 * @author Matthew Khouzam
36 * @author Geneviève Bastien
38 public class MemoryUsageStateProvider
extends AbstractTmfStateProvider
{
40 /* Version of this state provider */
41 private static final int VERSION
= 1;
43 /* Maps a pointer to a memory zone to the size of the memory */
44 private final Map
<Long
, Long
> fMemory
= new HashMap
<>();
46 private static final Long MINUS_ONE
= Long
.valueOf(-1);
47 private static final Long ZERO
= Long
.valueOf(0);
48 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
56 public MemoryUsageStateProvider(LttngUstTrace trace
) {
57 super(trace
, CtfTmfEvent
.class, "Ust:Memory"); //$NON-NLS-1$
61 protected void eventHandle(ITmfEvent event
) {
62 String name
= event
.getType().getName();
64 case UstMemoryStrings
.MALLOC
: {
65 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
66 if (ZERO
.equals(ptr
)) {
69 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
70 setMem(event
, ptr
, size
);
73 case UstMemoryStrings
.FREE
: {
74 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
75 if (ZERO
.equals(ptr
)) {
78 setMem(event
, ptr
, ZERO
);
81 case UstMemoryStrings
.CALLOC
: {
82 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
83 if (ZERO
.equals(ptr
)) {
86 Long nmemb
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_NMEMB
).getValue();
87 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
88 setMem(event
, ptr
, size
* nmemb
);
91 case UstMemoryStrings
.REALLOC
: {
92 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
93 if (ZERO
.equals(ptr
)) {
96 Long newPtr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_INPTR
).getValue();
97 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
98 setMem(event
, ptr
, ZERO
);
99 setMem(event
, newPtr
, size
);
102 case UstMemoryStrings
.MEMALIGN
: {
103 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
104 if (ZERO
.equals(ptr
)) {
107 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
108 setMem(event
, ptr
, size
);
111 case UstMemoryStrings
.POSIX_MEMALIGN
: {
112 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_OUTPTR
).getValue();
113 if (ZERO
.equals(ptr
)) {
116 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
117 setMem(event
, ptr
, size
);
127 public ITmfStateProvider
getNewInstance() {
128 return new MemoryUsageStateProvider(getTrace());
132 public LttngUstTrace
getTrace() {
133 return (LttngUstTrace
) super.getTrace();
137 public int getVersion() {
141 private static Long
getVtid(ITmfEvent event
) {
142 ITmfEventField field
= event
.getContent().getField(UstMemoryStrings
.CONTEXT_VTID
);
146 return (Long
) field
.getValue();
149 private static String
getProcname(ITmfEvent event
) {
150 ITmfEventField field
= event
.getContent().getField(UstMemoryStrings
.CONTEXT_PROCNAME
);
154 return (String
) field
.getValue();
157 private void setMem(ITmfEvent event
, Long ptr
, Long size
) {
158 long ts
= event
.getTimestamp().getValue();
159 Long tid
= getVtid(event
);
161 Long memoryDiff
= size
;
162 /* Size is 0, it means it was deleted */
163 if (ZERO
.equals(size
)) {
164 Long memSize
= fMemory
.remove(ptr
);
165 if (memSize
== null) {
168 memoryDiff
= -memSize
;
170 fMemory
.put(ptr
, size
);
173 int tidQuark
= ss
.getQuarkAbsoluteAndAdd(tid
.toString());
174 int tidMemQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_MEMORY_ATTRIBUTE
);
176 ITmfStateValue prevMem
= ss
.queryOngoingState(tidMemQuark
);
177 /* First time we set this value */
178 if (prevMem
.isNull()) {
179 int procNameQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_PROCNAME_ATTRIBUTE
);
180 String procName
= getProcname(event
);
182 * No tid/procname for the event for the event, added to a
185 if (tid
.equals(MINUS_ONE
)) {
186 procName
= UstMemoryStrings
.OTHERS
;
188 ss
.modifyAttribute(ts
, TmfStateValue
.newValueString(procName
), procNameQuark
);
189 prevMem
= TmfStateValue
.newValueLong(0);
192 long prevMemValue
= prevMem
.unboxLong();
193 prevMemValue
+= memoryDiff
.longValue();
194 ss
.modifyAttribute(ts
, TmfStateValue
.newValueLong(prevMemValue
), tidMemQuark
);
195 } catch (AttributeNotFoundException
| TimeRangeException
| StateValueTypeException e
) {
196 throw new IllegalStateException(e
);