1 /**********************************************************************
2 * Copyright (c) 2016 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
8 **********************************************************************/
9 package org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernelmemoryusage
;
11 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
13 import org
.eclipse
.jdt
.annotation
.NonNull
;
14 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.kernel
.KernelTidAspect
;
15 import org
.eclipse
.tracecompass
.analysis
.os
.linux
.core
.trace
.IKernelAnalysisEventLayout
;
16 import org
.eclipse
.tracecompass
.internal
.analysis
.os
.linux
.core
.Activator
;
17 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystemBuilder
;
18 import org
.eclipse
.tracecompass
.statesystem
.core
.StateSystemBuilderUtils
;
19 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
22 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
23 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.AbstractTmfStateProvider
;
24 import org
.eclipse
.tracecompass
.tmf
.core
.statesystem
.ITmfStateProvider
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
28 * Creates a state system and computes the total memory usage for all threads
29 * and for each selected thread from a kernel trace. It examines the page
30 * allocation and deallocation events in the kernel to do so.
32 * The state provider also contains code that can query the state system.
34 * @author Samuel Gagnon
37 public class KernelMemoryStateProvider
extends AbstractTmfStateProvider
{
40 * Special string to save memory allocation when tid is not known
42 public static final String OTHER_TID
= "other"; //$NON-NLS-1$
44 /* Version of this state provider */
45 private static final int VERSION
= 1;
47 private static final int PAGE_SIZE
= 4096;
49 private IKernelAnalysisEventLayout fLayout
;
59 public KernelMemoryStateProvider(@NonNull ITmfTrace trace
, IKernelAnalysisEventLayout layout
) {
60 super(trace
, "Kernel:Memory"); //$NON-NLS-1$
65 public int getVersion() {
70 public ITmfStateProvider
getNewInstance() {
71 return new KernelMemoryStateProvider(getTrace(), fLayout
);
75 protected void eventHandle(@NonNull ITmfEvent event
) {
76 String name
= event
.getName();
79 if (name
.equals(fLayout
.eventKmemPageAlloc())) {
81 } else if (name
.equals(fLayout
.eventKmemPageFree())) {
88 ITmfStateSystemBuilder ss
= checkNotNull(getStateSystemBuilder());
89 long ts
= event
.getTimestamp().getValue();
91 Integer tidField
= KernelTidAspect
.INSTANCE
.resolve(event
);
93 if (tidField
== null) {
94 // if the TID is not available
97 tid
= tidField
.toString();
100 int tidQuark
= ss
.getQuarkAbsoluteAndAdd(tid
);
101 StateSystemBuilderUtils
.incrementAttributeLong(ss
, ts
, tidQuark
, inc
);
102 long currentMemoryValue
= ss
.queryOngoingState(tidQuark
).unboxLong();
105 * We add an attribute to keep the lowest memory value for each
106 * thread. This quantity is used when we plot to avoid negative
109 int lowestMemoryQuark
= ss
.getQuarkRelativeAndAdd(tidQuark
, KernelMemoryAnalysisModule
.THREAD_LOWEST_MEMORY_VALUE
);
110 ITmfStateValue lowestMemoryValue
= ss
.queryOngoingState(lowestMemoryQuark
);
111 long previousLowest
= lowestMemoryValue
.isNull() ?
0 : lowestMemoryValue
.unboxLong();
113 if (previousLowest
> currentMemoryValue
) {
114 ss
.modifyAttribute(ts
, TmfStateValue
.newValueLong(currentMemoryValue
), lowestMemoryQuark
);
116 } catch (AttributeNotFoundException e
) {
117 Activator
.getDefault().logError(e
.getMessage(), e
);