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 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
;
33 import org
.eclipse
.tracecompass
.tmf
.ctf
.core
.event
.CtfTmfEvent
;
36 * State provider to track the memory of the threads using the UST libc wrapper
39 * @author Matthew Khouzam
40 * @author Geneviève Bastien
42 public class MemoryUsageStateProvider
extends AbstractTmfStateProvider
{
44 /* Version of this state provider */
45 private static final int VERSION
= 1;
47 /* Maps a pointer to a memory zone to the size of the memory */
48 private final Map
<Long
, Long
> fMemory
= new HashMap
<>();
50 private static final Long MINUS_ONE
= Long
.valueOf(-1);
51 private static final Long ZERO
= Long
.valueOf(0);
52 private static final String EMPTY_STRING
= ""; //$NON-NLS-1$
60 public MemoryUsageStateProvider(@NonNull LttngUstTrace trace
) {
61 super(trace
, CtfTmfEvent
.class, "Ust:Memory"); //$NON-NLS-1$
65 protected void eventHandle(ITmfEvent event
) {
66 String name
= event
.getType().getName();
68 case UstMemoryStrings
.MALLOC
: {
69 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
70 if (ZERO
.equals(ptr
)) {
73 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
74 setMem(event
, ptr
, size
);
77 case UstMemoryStrings
.FREE
: {
78 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
79 if (ZERO
.equals(ptr
)) {
82 setMem(event
, ptr
, ZERO
);
85 case UstMemoryStrings
.CALLOC
: {
86 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
87 if (ZERO
.equals(ptr
)) {
90 Long nmemb
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_NMEMB
).getValue();
91 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
92 setMem(event
, ptr
, size
* nmemb
);
95 case UstMemoryStrings
.REALLOC
: {
96 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
97 if (ZERO
.equals(ptr
)) {
100 Long newPtr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_INPTR
).getValue();
101 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
102 setMem(event
, ptr
, ZERO
);
103 setMem(event
, newPtr
, size
);
106 case UstMemoryStrings
.MEMALIGN
: {
107 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_PTR
).getValue();
108 if (ZERO
.equals(ptr
)) {
111 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
112 setMem(event
, ptr
, size
);
115 case UstMemoryStrings
.POSIX_MEMALIGN
: {
116 Long ptr
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_OUTPTR
).getValue();
117 if (ZERO
.equals(ptr
)) {
120 Long size
= (Long
) event
.getContent().getField(UstMemoryStrings
.FIELD_SIZE
).getValue();
121 setMem(event
, ptr
, size
);
131 public ITmfStateProvider
getNewInstance() {
132 return new MemoryUsageStateProvider(getTrace());
136 public LttngUstTrace
getTrace() {
137 return (LttngUstTrace
) super.getTrace();
141 public int getVersion() {
145 private static Long
getVtid(ITmfEvent event
) {
146 ITmfEventField field
= event
.getContent().getField(UstMemoryStrings
.CONTEXT_VTID
);
150 return (Long
) field
.getValue();
153 private static String
getProcname(ITmfEvent event
) {
154 ITmfEventField field
= event
.getContent().getField(UstMemoryStrings
.CONTEXT_PROCNAME
);
158 return (String
) field
.getValue();
161 private void setMem(ITmfEvent event
, Long ptr
, Long size
) {
162 ITmfStateSystemBuilder ss
= checkNotNull(getStateSystemBuilder());
163 long ts
= event
.getTimestamp().getValue();
164 Long tid
= getVtid(event
);
166 Long memoryDiff
= size
;
167 /* Size is 0, it means it was deleted */
168 if (ZERO
.equals(size
)) {
169 Long memSize
= fMemory
.remove(ptr
);
170 if (memSize
== null) {
173 memoryDiff
= -memSize
;
175 fMemory
.put(ptr
, size
);
178 int tidQuark
= ss
.getQuarkAbsoluteAndAdd(tid
.toString());
179 int tidMemQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_MEMORY_ATTRIBUTE
);
181 ITmfStateValue prevMem
= ss
.queryOngoingState(tidMemQuark
);
182 /* First time we set this value */
183 if (prevMem
.isNull()) {
184 int procNameQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, UstMemoryStrings
.UST_MEMORY_PROCNAME_ATTRIBUTE
);
185 String procName
= getProcname(event
);
187 * No tid/procname for the event for the event, added to a
190 if (tid
.equals(MINUS_ONE
)) {
191 procName
= UstMemoryStrings
.OTHERS
;
193 ss
.modifyAttribute(ts
, TmfStateValue
.newValueString(procName
), procNameQuark
);
194 prevMem
= TmfStateValue
.newValueLong(0);
197 long prevMemValue
= prevMem
.unboxLong();
198 prevMemValue
+= memoryDiff
.longValue();
199 ss
.modifyAttribute(ts
, TmfStateValue
.newValueLong(prevMemValue
), tidMemQuark
);
200 } catch (AttributeNotFoundException
| TimeRangeException
| StateValueTypeException e
) {
201 throw new IllegalStateException(e
);