|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.carbide.cpp.pi.graphicsmemory; |
|
19 |
|
20 import java.util.ArrayList; |
|
21 import java.util.Enumeration; |
|
22 import java.util.HashSet; |
|
23 import java.util.Hashtable; |
|
24 import java.util.Iterator; |
|
25 import java.util.SortedMap; |
|
26 import java.util.TreeMap; |
|
27 |
|
28 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository; |
|
29 import com.nokia.carbide.cpp.internal.pi.model.GenericSample; |
|
30 import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace; |
|
31 import com.nokia.carbide.cpp.internal.pi.model.GenericThread; |
|
32 import com.nokia.carbide.cpp.internal.pi.model.TraceWithThreads; |
|
33 import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph; |
|
34 import com.nokia.carbide.cpp.pi.editors.PIPageEditor; |
|
35 |
|
36 public class GraphicsMemoryTrace extends GenericSampledTrace implements |
|
37 TraceWithThreads { |
|
38 static final long serialVersionUID = 3606238546911055987L; |
|
39 |
|
40 private transient GraphicsMemoryTraceGraph[] graphs; |
|
41 private GraphicsMemoryProcess[] processArray; |
|
42 |
|
43 // maximums for the entire trace |
|
44 transient private int traceMaxPrivate = 0; |
|
45 transient private int traceMaxShared = 0; |
|
46 transient private int traceMaxTotal = 0; |
|
47 transient private int traceTotalMemory = 0; |
|
48 |
|
49 transient private Hashtable<String, TreeMap<Long, GraphicsMemorySample>> drawDataByMemProcess = null; |
|
50 transient private ArrayList<GraphicsMemorySampleByTime> drawDataByTime; |
|
51 transient private HashSet<GraphicsMemoryProcess> noDuplicateMemProcesses; |
|
52 |
|
53 transient private long intervalStart = -1; |
|
54 transient private long intervalEnd = -1; |
|
55 |
|
56 private int version; |
|
57 |
|
58 public GraphicsMemoryTrace() { |
|
59 } |
|
60 |
|
61 public GenericThread[] getThreads() { |
|
62 return processArray; |
|
63 } |
|
64 |
|
65 public void setProcesses(GraphicsMemoryProcess[] processArray) { |
|
66 this.processArray = processArray; |
|
67 } |
|
68 |
|
69 public int getTraceMaxPrivate() { |
|
70 return traceMaxPrivate; |
|
71 } |
|
72 |
|
73 public int getTraceMaxShared() { |
|
74 return traceMaxShared; |
|
75 } |
|
76 |
|
77 public int getTraceMaxTotal() { |
|
78 return traceMaxTotal; |
|
79 } |
|
80 |
|
81 public int getTraceTotalMemory() { |
|
82 return traceTotalMemory; |
|
83 } |
|
84 |
|
85 public void setTraceTotalMemory(int traceTotalMemory) { |
|
86 this.traceTotalMemory = traceTotalMemory; |
|
87 } |
|
88 |
|
89 public void setTraceMaxShared(int traceMaxShared) { |
|
90 this.traceMaxShared = traceMaxShared; |
|
91 } |
|
92 |
|
93 public void setTraceMaxTotal(int traceMaxTotal) { |
|
94 this.traceMaxTotal = traceMaxTotal; |
|
95 } |
|
96 |
|
97 public void setTraceMaxPrivate(int traceMaxPrivate) { |
|
98 this.traceMaxPrivate = traceMaxPrivate; |
|
99 } |
|
100 |
|
101 public int getVersion() { |
|
102 return this.version; |
|
103 } |
|
104 |
|
105 public void setVersion(int version) { |
|
106 this.version = version; |
|
107 } |
|
108 |
|
109 public GenericTraceGraph getTraceGraph(int graphIndex) { |
|
110 if (graphs == null) { |
|
111 graphs = new GraphicsMemoryTraceGraph[3]; |
|
112 } |
|
113 |
|
114 // note that graphIndex need not match the index sent to |
|
115 // GraphicsMemoryTraceGraph |
|
116 if ((graphIndex == PIPageEditor.THREADS_PAGE) |
|
117 || (graphIndex == PIPageEditor.BINARIES_PAGE) |
|
118 || (graphIndex == PIPageEditor.FUNCTIONS_PAGE)) { |
|
119 if (graphs[graphIndex] == null) { |
|
120 int uid = NpiInstanceRepository.getInstance().activeUid(); |
|
121 graphs[graphIndex] = new GraphicsMemoryTraceGraph(graphIndex, |
|
122 this, uid); |
|
123 } |
|
124 return graphs[graphIndex]; |
|
125 } |
|
126 return null; |
|
127 } |
|
128 |
|
129 public void gatherDrawData() { |
|
130 if (drawDataByMemProcess != null) |
|
131 return; // already initialised |
|
132 drawDataByMemProcess = new Hashtable<String, TreeMap<Long, GraphicsMemorySample>>(); |
|
133 |
|
134 getProcessesFromTrace(); |
|
135 |
|
136 if (drawDataByTime == null) |
|
137 drawDataByTime = new ArrayList<GraphicsMemorySampleByTime>(); |
|
138 |
|
139 // index each sample by process name and by sample time |
|
140 for (Enumeration<GenericSample> e = this.getSamples(); e |
|
141 .hasMoreElements();) { |
|
142 addSampleToProcess((GraphicsMemorySample) e.nextElement()); |
|
143 } |
|
144 } |
|
145 |
|
146 private void addSampleToProcess(GraphicsMemorySample sample) { |
|
147 // get sample array from process |
|
148 TreeMap<Long, GraphicsMemorySample> samples = drawDataByMemProcess |
|
149 .get(sample.process.fullName); |
|
150 |
|
151 if (samples != null) { |
|
152 // Add initial sample to process |
|
153 samples.put(sample.sampleSynchTime, sample); |
|
154 return; |
|
155 } |
|
156 |
|
157 System.out.println("PI ERROR: Process not found"); //$NON-NLS-1$ |
|
158 } |
|
159 |
|
160 private void getProcessesFromTrace() { |
|
161 |
|
162 noDuplicateMemProcesses = new HashSet<GraphicsMemoryProcess>(131, 0.75f); |
|
163 |
|
164 // the parser creates multiple copies of the same GraphicsMemoryProcess item, |
|
165 // so we have to use the full name of the GraphicsMemoryProcess to access sample |
|
166 // data |
|
167 |
|
168 for (GraphicsMemoryProcess memProcess : processArray) { |
|
169 memProcess.fullName = memProcess.processName; |
|
170 memProcess.enabled = new boolean[3]; |
|
171 memProcess.enabled[0] = true; |
|
172 memProcess.enabled[1] = true; |
|
173 memProcess.enabled[2] = true; |
|
174 |
|
175 memProcess.maxMemoryItem = new MaxGraphicsMemoryItem(); |
|
176 memProcess.maxMemoryItem.maxPrivate = 0; |
|
177 memProcess.maxMemoryItem.maxShared = 0; |
|
178 memProcess.maxMemoryItem.maxTotal = 0; |
|
179 |
|
180 if (drawDataByMemProcess.get(memProcess.fullName) == null) { |
|
181 drawDataByMemProcess.put(memProcess.fullName, |
|
182 new TreeMap<Long, GraphicsMemorySample>()); |
|
183 noDuplicateMemProcesses.add(memProcess); |
|
184 } |
|
185 } |
|
186 } |
|
187 |
|
188 public TreeMap<Long, GraphicsMemorySample> getDrawDataByMemProcess( |
|
189 GraphicsMemoryProcess id) { |
|
190 return this.drawDataByMemProcess.get(id.fullName); |
|
191 } |
|
192 |
|
193 public Hashtable<String, TreeMap<Long, GraphicsMemorySample>> getDrawDataByMemProcess() { |
|
194 return this.drawDataByMemProcess; |
|
195 } |
|
196 |
|
197 public ArrayList<GraphicsMemorySampleByTime> getDrawDataByTime() { |
|
198 |
|
199 if (drawDataByTime.isEmpty()) { |
|
200 TreeMap<Long, GraphicsMemorySample> events = drawDataByMemProcess |
|
201 .get(GraphicsMemoryTraceParser.SAMPLE_TOTAL_MEMORY_PROCESS_NAME); //$NON-NLS-1$ |
|
202 |
|
203 Iterator<GraphicsMemorySample> iterator = events.values() |
|
204 .iterator(); |
|
205 while (iterator.hasNext()) { |
|
206 GraphicsMemorySample memSample = iterator.next(); |
|
207 drawDataByTime.add(new GraphicsMemorySampleByTime( |
|
208 memSample.sampleSynchTime, memSample.sharedSize, |
|
209 memSample.privateSize)); |
|
210 } |
|
211 } |
|
212 return this.drawDataByTime; |
|
213 } |
|
214 |
|
215 public HashSet<GraphicsMemoryProcess> getNoDuplicateMemProcesses() { |
|
216 return this.noDuplicateMemProcesses; |
|
217 } |
|
218 |
|
219 public ArrayList<GraphicsMemorySample> getMemSampleDataByTime(long time) { |
|
220 if ((this.drawDataByTime == null) |
|
221 || (time < this.drawDataByTime.get(0).getTime())) |
|
222 return null; |
|
223 |
|
224 int i = 0; |
|
225 for (; i < this.drawDataByTime.size(); i++) { |
|
226 GraphicsMemorySampleByTime sample = this.drawDataByTime.get(i); |
|
227 if (sample.getTime() > time) |
|
228 break; |
|
229 } |
|
230 |
|
231 return this.drawDataByTime.get(i - 1).getSamples(); |
|
232 } |
|
233 |
|
234 public MaxGraphicsMemoryItem getSystemUseByInterval(long startTime, |
|
235 long endTime) { |
|
236 MaxGraphicsMemoryItem item = new MaxGraphicsMemoryItem(); |
|
237 |
|
238 if ((this.drawDataByTime == null) |
|
239 || ((startTime == intervalStart) && (endTime == intervalEnd))) |
|
240 return item; |
|
241 |
|
242 if (this.getVersion() == 100) { |
|
243 TreeMap<Long, GraphicsMemorySample> events = drawDataByMemProcess |
|
244 .get(GraphicsMemoryTraceParser.SAMPLE_TOTAL_MEMORY_PROCESS_NAME); //$NON-NLS-1$ |
|
245 |
|
246 GraphicsMemorySample floorSample = (GraphicsMemorySample) GraphicsMemoryTrace |
|
247 .getFloorEntryFromMap(startTime, events); |
|
248 |
|
249 if(floorSample != null){ |
|
250 item.maxPrivate = floorSample.privateSize; |
|
251 item.maxTotal = floorSample.sharedSize; |
|
252 } |
|
253 |
|
254 SortedMap<Long, GraphicsMemorySample> sortedMap = events.subMap(startTime, endTime); |
|
255 Iterator<GraphicsMemorySample> values = sortedMap.values().iterator(); |
|
256 |
|
257 while (values.hasNext()) { |
|
258 GraphicsMemorySample memSample = values.next(); |
|
259 // store system used memory as privates and total memory as total |
|
260 if (item.maxPrivate < memSample.privateSize) |
|
261 item.maxPrivate = memSample.privateSize; |
|
262 item.maxTotal = memSample.sharedSize; |
|
263 if (memSample.sampleSynchTime > endTime) |
|
264 break; |
|
265 |
|
266 } |
|
267 |
|
268 } |
|
269 return item; |
|
270 } |
|
271 |
|
272 public void setMaxMemDataByInterval(long startTime, long endTime) { |
|
273 |
|
274 // Set all values to zero |
|
275 for (int i = 0; i < processArray.length; i++) { |
|
276 MaxGraphicsMemoryItem item = processArray[i].maxMemoryItem; |
|
277 item.maxPrivate = 0; |
|
278 item.maxShared = 0; |
|
279 item.maxTotal = 0; |
|
280 } |
|
281 |
|
282 // if no data is found between start and end time or start and end |
|
283 // times are same with previous. |
|
284 if ((this.drawDataByTime == null) |
|
285 || ((startTime == intervalStart) && (endTime == intervalEnd))) |
|
286 return; |
|
287 |
|
288 if (this.version == 100) { |
|
289 |
|
290 for (Enumeration<TreeMap<Long, GraphicsMemorySample>> e = drawDataByMemProcess |
|
291 .elements(); e.hasMoreElements();) { |
|
292 TreeMap<Long, GraphicsMemorySample> memSamples = (TreeMap<Long, GraphicsMemorySample>) e |
|
293 .nextElement(); |
|
294 |
|
295 if (memSamples.size() == 0) { |
|
296 continue; |
|
297 } |
|
298 |
|
299 GraphicsMemorySample firstSample = (GraphicsMemorySample) memSamples |
|
300 .get(memSamples.firstKey()); |
|
301 |
|
302 GraphicsMemoryProcess process = firstSample.process; |
|
303 |
|
304 MaxGraphicsMemoryItem maxMemoryItem = process.maxMemoryItem; |
|
305 |
|
306 SortedMap<Long, GraphicsMemorySample> subMap = memSamples |
|
307 .subMap(startTime, endTime); |
|
308 |
|
309 ArrayList<GraphicsMemorySample> samples = new ArrayList<GraphicsMemorySample>( |
|
310 subMap.values()); |
|
311 |
|
312 GraphicsMemorySample floorSample = (GraphicsMemorySample) GraphicsMemoryTrace |
|
313 .getFloorEntryFromMap(startTime, memSamples); |
|
314 |
|
315 if (floorSample != null) { |
|
316 |
|
317 maxMemoryItem.maxPrivate = floorSample.privateSize; |
|
318 maxMemoryItem.maxShared = floorSample.sharedSize; |
|
319 maxMemoryItem.maxTotal = floorSample.privateSize |
|
320 + floorSample.sharedSize; |
|
321 |
|
322 } |
|
323 |
|
324 for (GraphicsMemorySample item : samples) { |
|
325 if (maxMemoryItem.maxPrivate < item.privateSize) { |
|
326 maxMemoryItem.maxPrivate = item.privateSize; |
|
327 } |
|
328 if (maxMemoryItem.maxShared < item.sharedSize) { |
|
329 maxMemoryItem.maxShared = item.sharedSize; |
|
330 } |
|
331 if (maxMemoryItem.maxTotal < item.privateSize |
|
332 + item.sharedSize) { |
|
333 maxMemoryItem.maxTotal = item.privateSize |
|
334 + item.sharedSize; |
|
335 } |
|
336 } |
|
337 } |
|
338 } |
|
339 } |
|
340 |
|
341 @SuppressWarnings("unchecked") |
|
342 public static Object getFloorEntryFromMap(long key, TreeMap map) { |
|
343 // TODO if JDK 6 is in use this should be used: |
|
344 // return map.floorEntry(key).getValue(); |
|
345 |
|
346 // when JDK 5 in use use this: |
|
347 try { |
|
348 SortedMap headMap = map.headMap(key); |
|
349 return headMap.get(headMap.lastKey()); |
|
350 } catch (Exception e) { |
|
351 return null; |
|
352 } |
|
353 |
|
354 } |
|
355 } |