|
1 /* |
|
2 * Copyright (c) 2008 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 "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: Main classes for Graphics Out of Memory Monitor |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #define USE_ASYNCYH_NOTIFICATIONS |
|
20 |
|
21 |
|
22 #include <hal.h> |
|
23 #include <libc/string.h> |
|
24 #include <UikonInternalPSKeys.h> |
|
25 |
|
26 //TODO: to be removed for wk44 onwards, should use only <EGL/egl.h> which is already included in goommemorymonitor.h |
|
27 #ifdef USE_ASYNCYH_NOTIFICATIONS |
|
28 #include <EGL/egl.h> |
|
29 #else // use local |
|
30 #include "eglext.h" |
|
31 #endif |
|
32 |
|
33 #include "goommemorymonitor.h" |
|
34 #include "goommonitorplugin.h" |
|
35 #include "goomconfig.h" |
|
36 #include "goommemorymonitorserver.h" |
|
37 #include "goomconfigparser.h" |
|
38 #include "goomactionlist.h" |
|
39 #include "goomlog.h" |
|
40 #include "goomtraces.h" |
|
41 #include "goomwserveventreceiver.h" |
|
42 #include "goomconstants.hrh" |
|
43 #include "goomrunpluginconfig.h" |
|
44 #include "goomapplicationconfig.h" |
|
45 #include "goomcloseappconfig.h" |
|
46 #include <goommonitorsession.h> |
|
47 #ifdef USE_ASYNCYH_NOTIFICATIONS |
|
48 #include "goomthresholdcrossedao.inl" |
|
49 #endif |
|
50 |
|
51 // ====================================================================== |
|
52 // class CMemoryMonitor |
|
53 // ====================================================================== |
|
54 |
|
55 // --------------------------------------------------------- |
|
56 // |
|
57 // --------------------------------------------------------- |
|
58 // |
|
59 CMemoryMonitor* CMemoryMonitor::NewL() |
|
60 { // static |
|
61 FUNC_LOG; |
|
62 |
|
63 CMemoryMonitor* self = new(ELeave) CMemoryMonitor(); |
|
64 CleanupStack::PushL(self); |
|
65 self->ConstructL(); |
|
66 CleanupStack::Pop(self); |
|
67 return self; |
|
68 } |
|
69 |
|
70 CMemoryMonitor::CMemoryMonitor() |
|
71 { |
|
72 FUNC_LOG; |
|
73 |
|
74 SetGMemoryMonitorTls(this); |
|
75 } |
|
76 |
|
77 // --------------------------------------------------------- |
|
78 // |
|
79 // --------------------------------------------------------- |
|
80 // |
|
81 CMemoryMonitor::~CMemoryMonitor() |
|
82 { |
|
83 FUNC_LOG; |
|
84 |
|
85 delete iServer; |
|
86 delete iWservEventReceiver; |
|
87 iFs.Close(); |
|
88 iWs.Close(); |
|
89 |
|
90 delete iGOomWindowGroupList; |
|
91 |
|
92 delete iGOomActionList; |
|
93 |
|
94 delete iConfig; |
|
95 |
|
96 #ifdef USE_ASYNCYH_NOTIFICATIONS |
|
97 delete iMemAllocationsGrowing; |
|
98 delete iMemAllocationsGoingDown; |
|
99 #endif |
|
100 |
|
101 eglTerminate(eglGetDisplay(EGL_DEFAULT_DISPLAY)); |
|
102 |
|
103 #ifdef _DEBUG |
|
104 delete iLogger; |
|
105 #endif |
|
106 } |
|
107 |
|
108 // --------------------------------------------------------- |
|
109 // |
|
110 // --------------------------------------------------------- |
|
111 // |
|
112 void CMemoryMonitor::ConstructL() |
|
113 { |
|
114 FUNC_LOG; |
|
115 |
|
116 //Initialize EGL extension for memory data |
|
117 |
|
118 EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
|
119 EGLint major, minor; |
|
120 eglInitialize(dpy, &major, &minor); |
|
121 |
|
122 /* |
|
123 ** Search for extName in the extensions string. Use of strstr() |
|
124 ** is not sufficient because extension names can be prefixes of |
|
125 ** other extension names. Could use strtok() but the constant |
|
126 ** string returned by glGetString can be in read-only memory. |
|
127 */ |
|
128 TBool extensionFound = EFalse; |
|
129 char *p = (char *) eglQueryString(dpy,EGL_EXTENSIONS); |
|
130 char *end; |
|
131 int extNameLen; |
|
132 |
|
133 extNameLen = strlen("EGL_NOK_resource_profiling"); |
|
134 end = p + strlen(p); |
|
135 |
|
136 while (p < end) |
|
137 { |
|
138 int n = strcspn(p, " "); |
|
139 if ((extNameLen == n) && (strncmp("EGL_NOK_resource_profiling", p, n) == 0)) |
|
140 { |
|
141 extensionFound = ETrue; |
|
142 break; |
|
143 } |
|
144 p += (n + 1); |
|
145 } |
|
146 |
|
147 if (!extensionFound) |
|
148 { |
|
149 TRACES("EGL_NOK_resource_profiling not found from EGL_EXTENSIONS"); |
|
150 } |
|
151 // okay, let's fetch the function ptr to our profiling functions |
|
152 eglQueryProfilingData = (NOK_resource_profiling)eglGetProcAddress("eglQueryProfilingDataNOK"); |
|
153 if (!eglQueryProfilingData) |
|
154 { |
|
155 TRACES("eglQueryProfilingDataNOK not found via eglGetProcAddress()"); |
|
156 User::Leave(KErrNotSupported); |
|
157 } |
|
158 |
|
159 User::LeaveIfError(iWs.Connect()); |
|
160 iWs.ComputeMode(RWsSession::EPriorityControlDisabled); |
|
161 |
|
162 iGOomWindowGroupList = CGOomWindowGroupList::NewL(iWs); |
|
163 |
|
164 iConfig = CGOomConfig::NewL(); |
|
165 |
|
166 iServer = CMemoryMonitorServer::NewL(*this); |
|
167 |
|
168 // Load up threshold & OOM app lists from resource. |
|
169 User::LeaveIfError(iFs.Connect()); |
|
170 |
|
171 CGOomConfigParser* oomConfigParser = new (ELeave) CGOomConfigParser(*iConfig, iFs); |
|
172 CleanupStack::PushL(oomConfigParser); |
|
173 oomConfigParser->ParseL(); |
|
174 CleanupStack::PopAndDestroy(oomConfigParser); |
|
175 |
|
176 iGOomActionList = CGOomActionList::NewL(*this, *iServer, iWs, *iConfig); |
|
177 |
|
178 #ifdef _DEBUG |
|
179 iLogger = CGOomLogger::NewL(iWs, iFs); |
|
180 #endif |
|
181 |
|
182 // Get the thresholds based on the current foreground app and the config |
|
183 RefreshThresholds(); |
|
184 |
|
185 iWservEventReceiver = new(ELeave) CWservEventReceiver(*this, iWs); |
|
186 iWservEventReceiver->ConstructL(); |
|
187 } |
|
188 |
|
189 const CGOomGlobalConfig& CMemoryMonitor::GlobalConfig() |
|
190 { |
|
191 CMemoryMonitor* globalMemoryMonitor = static_cast<CMemoryMonitor*>(Dll::Tls()); |
|
192 return globalMemoryMonitor->iConfig->GlobalConfig(); |
|
193 } |
|
194 |
|
195 |
|
196 // --------------------------------------------------------- |
|
197 // |
|
198 // --------------------------------------------------------- |
|
199 // |
|
200 void CMemoryMonitor::FreeMemThresholdCrossedL(TInt /*aAction*/, TInt aThreshold) |
|
201 { |
|
202 FUNC_LOG; |
|
203 // keep only one notification active at a moment |
|
204 #ifdef USE_ASYNCYH_NOTIFICATIONS |
|
205 if (aThreshold == EGL_PROF_TOTAL_MEMORY_USAGE_GT_NOK) |
|
206 { |
|
207 TRACES("FreeMemThresholdCrossedL : EGL_PROF_TOTAL_MEMORY_USAGE_GT_NOK"); |
|
208 iMemAllocationsGrowing->Stop(); |
|
209 iMemAllocationsGoingDown->Continue(); |
|
210 } |
|
211 else |
|
212 { |
|
213 TRACES("FreeMemThresholdCrossedL : EGL_PROF_TOTAL_MEMORY_USAGE_LT_NOK"); |
|
214 iMemAllocationsGrowing->Continue(); |
|
215 iMemAllocationsGoingDown->Stop(); |
|
216 } |
|
217 #endif |
|
218 |
|
219 StartFreeSomeRamL(iGoodThreshold); |
|
220 if (aThreshold == EGL_PROF_TOTAL_MEMORY_USAGE_LT_NOK) |
|
221 { |
|
222 TInt current = GetFreeMemory(); |
|
223 if(current >= iGoodThreshold && (!NeedToPostponeMemGood())) |
|
224 { |
|
225 TRACES("FreeMemThresholdCrossedL : calling MemoryGOOD"); |
|
226 iGOomActionList->MemoryGood(); |
|
227 } |
|
228 } |
|
229 } |
|
230 |
|
231 void CMemoryMonitor::HandleFocusedWgChangeL(TInt aForegroundAppUid) |
|
232 { |
|
233 FUNC_LOG; |
|
234 |
|
235 TRACES1("CMemoryMonitor::HandleFocusedWgChangeL Foregroundapp id = %x", aForegroundAppUid); |
|
236 |
|
237 if(aForegroundAppUid == 0) |
|
238 { |
|
239 return; |
|
240 } |
|
241 iForegroundAppUid = aForegroundAppUid; |
|
242 |
|
243 // Refresh the low and good memory thresholds as they may have changed due to the new foreground application |
|
244 RefreshThresholds(aForegroundAppUid); |
|
245 // Not very elegant, now we poll on each window group change |
|
246 // Should have better trigger e.g. from window server |
|
247 #ifndef USE_ASYNCYH_NOTIFICATIONS |
|
248 TInt current = GetFreeMemory(); |
|
249 if (current < iLowThreshold) |
|
250 { |
|
251 StartFreeSomeRamL(iGoodThreshold); |
|
252 } |
|
253 else if(current >= iGoodThreshold) |
|
254 { |
|
255 iGOomActionList->MemoryGood(); |
|
256 } |
|
257 #endif |
|
258 } |
|
259 |
|
260 void CMemoryMonitor::StartFreeSomeRamL(TInt aTargetFree, TInt aMaxPriority) // The maximum priority of action to run |
|
261 { |
|
262 FUNC_LOG; |
|
263 |
|
264 TRACES2("MemoryMonitor::StartFreeSomeRamL: aTargetFree = %d, iCurrentTarget = %d", aTargetFree, iCurrentTarget); |
|
265 |
|
266 // Update the target if new target is higher. If the target is lower than the current target and memory |
|
267 // is currently being freed then we do not want to reduce the amount of memory this operation frees. |
|
268 if (aTargetFree > iCurrentTarget) |
|
269 iCurrentTarget = aTargetFree; |
|
270 |
|
271 // check if there is enough free memory already. |
|
272 TInt freeMemory; |
|
273 TBool freeMemoryAboveCurrentTarget = FreeGraphicsMemoryAboveThresholdL(freeMemory); |
|
274 |
|
275 TRACES2("MemoryMonitor::StartFreeSomeRamL freeMemoryAboveTarget = %d, freeMemory = %d", freeMemoryAboveCurrentTarget, freeMemory); |
|
276 |
|
277 if (freeMemoryAboveCurrentTarget) |
|
278 { |
|
279 ResetTargets(); |
|
280 /*if(freeMemory >= iGoodThreshold && !NeedToPostponeMemGood()) |
|
281 { |
|
282 iGOomActionList->MemoryGood(); |
|
283 } |
|
284 */ |
|
285 iServer->CloseAppsFinished(freeMemory, ETrue); |
|
286 return; |
|
287 } |
|
288 |
|
289 // update wg list only when actually about to use it |
|
290 //iGOomWindowGroupList->Refresh(); |
|
291 |
|
292 #ifdef _DEBUG |
|
293 iLogger->StartL(); |
|
294 #endif |
|
295 |
|
296 // Build the list of memory freeing actions |
|
297 iGOomActionList->BuildPluginActionListL(*iGOomWindowGroupList, *iConfig); |
|
298 |
|
299 //iGOomActionList->SetCurrentTarget(aTargetFree); |
|
300 iGOomActionList->SetCurrentTarget(iCurrentTarget); |
|
301 |
|
302 // Run the memory freeing actions |
|
303 iGOomActionList->FreeMemory(aMaxPriority); |
|
304 } |
|
305 |
|
306 void CMemoryMonitor::RunCloseAppActions(TInt aMaxPriority) |
|
307 { |
|
308 FUNC_LOG; |
|
309 // Build the list of memory freeing actions (by killing apps) |
|
310 iGOomActionList->BuildKillAppActionListL(*iGOomWindowGroupList, *iConfig); |
|
311 iGOomActionList->FreeMemory(aMaxPriority); |
|
312 } |
|
313 |
|
314 // --------------------------------------------------------- |
|
315 // This function attempts to free enough RAM to leave the target amount of space free. |
|
316 // This function could take a substantial time to return as it may have to close a number |
|
317 // of applications, and each will be given a timeout of KAPPEXITTIMEOUT. |
|
318 // --------------------------------------------------------- |
|
319 // |
|
320 void CMemoryMonitor::StartFreeSomeRamL(TInt aTargetFree) |
|
321 { |
|
322 FUNC_LOG; |
|
323 |
|
324 StartFreeSomeRamL(aTargetFree, KGOomPriorityInfinate - 1); |
|
325 } |
|
326 |
|
327 void CMemoryMonitor::RequestFreeMemoryL(TInt aTargetFree, TBool aUseAbsolute) |
|
328 { |
|
329 FUNC_LOG; |
|
330 |
|
331 StartFreeSomeRamL(aUseAbsolute?aTargetFree:(aTargetFree + iLowThreshold), KGOomPriorityInfinate - 1); |
|
332 } |
|
333 |
|
334 void CMemoryMonitor::FreeOptionalRamL(TInt aTargetFree, TInt aPluginId, TBool aUseAbsolute) // The ID of the plugin that will clear up the allocation, used to determine the priority of the allocation |
|
335 { |
|
336 FUNC_LOG; |
|
337 |
|
338 // Calculate the priority of the allocation (the priority of the plugin that will clear it up - 1) |
|
339 TInt priorityOfAllocation = iConfig->GetPluginConfig(aPluginId).CalculatePluginPriority(*iGOomWindowGroupList) - 1; |
|
340 StartFreeSomeRamL(aUseAbsolute?aTargetFree:(aTargetFree + iGoodThreshold), priorityOfAllocation); |
|
341 } |
|
342 |
|
343 // Does the EGL extension return the amount of memory in bits? |
|
344 // If yes, int is clearly not enough |
|
345 // Note that this function reserves memory so it can fail if the "standard" memory |
|
346 // gets full. |
|
347 TBool CMemoryMonitor::FreeGraphicsMemoryAboveThresholdL(TInt& aCurrentFreeMemory) |
|
348 { |
|
349 FUNC_LOG; |
|
350 |
|
351 TInt current = GetFreeMemory(); |
|
352 User::LeaveIfError(current); |
|
353 aCurrentFreeMemory = current; |
|
354 |
|
355 return (current >= iCurrentTarget); |
|
356 } |
|
357 |
|
358 // --------------------------------------------------------- |
|
359 // |
|
360 // --------------------------------------------------------- |
|
361 // |
|
362 |
|
363 void CMemoryMonitor::AppNotExiting(TInt aWgId) |
|
364 { |
|
365 FUNC_LOG; |
|
366 |
|
367 iGOomActionList->AppNotExiting(aWgId); |
|
368 } |
|
369 |
|
370 |
|
371 void CMemoryMonitor::RefreshThresholds(TInt aForegroundAppUid) |
|
372 { |
|
373 FUNC_LOG; |
|
374 |
|
375 TInt origGood = iGoodThreshold; |
|
376 TInt origLow = iLowThreshold; |
|
377 |
|
378 // Calculate the desired good threshold, this could be the globally configured value... |
|
379 iGoodThreshold = CMemoryMonitor::GlobalConfig().iGoodRamThreshold; |
|
380 iLowThreshold = CMemoryMonitor::GlobalConfig().iLowRamThreshold; |
|
381 iCurrentTarget = iGoodThreshold; |
|
382 |
|
383 TRACES2("CMemoryMonitor::RefreshThresholds: Global Good Threshold = %d, Global Low Threshold = %d", iGoodThreshold, iLowThreshold); |
|
384 |
|
385 // The global value can be overridden by an app specific value |
|
386 // Find the application config entry for the foreground application |
|
387 if (aForegroundAppUid == KErrNotFound) |
|
388 { |
|
389 return; |
|
390 } |
|
391 |
|
392 // If this application configuration overrides the good_ram_threshold then set it |
|
393 if (iConfig->GetApplicationConfig(aForegroundAppUid).iGoodRamThreshold != KGOomThresholdUnset) |
|
394 { |
|
395 iGoodThreshold = iConfig->GetApplicationConfig(aForegroundAppUid).iGoodRamThreshold; |
|
396 TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Good Threshold = %d", aForegroundAppUid, iGoodThreshold); |
|
397 } |
|
398 |
|
399 // If this application configuration overrides the low_ram_threshold then set it |
|
400 if (iConfig->GetApplicationConfig(aForegroundAppUid).iLowRamThreshold != KGOomThresholdUnset) |
|
401 { |
|
402 iLowThreshold = iConfig->GetApplicationConfig(aForegroundAppUid).iLowRamThreshold; |
|
403 TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Low Threshold = %d", aForegroundAppUid, iLowThreshold); |
|
404 } |
|
405 |
|
406 // If this application configuration overrides the good_ram_threshold then set it |
|
407 if (iConfig->GetApplicationConfig(aForegroundAppUid).iTargetFree != KGOomThresholdUnset) |
|
408 { |
|
409 iCurrentTarget = iConfig->GetApplicationConfig(aForegroundAppUid).iTargetFree; |
|
410 TRACES2("CMemoryMonitor::RefreshThresholds: For foreground app %x, Target Free on Startup = %d", aForegroundAppUid, iCurrentTarget); |
|
411 } |
|
412 |
|
413 iGOomActionList->SetCurrentTarget(iCurrentTarget); |
|
414 |
|
415 #ifdef USE_ASYNCYH_NOTIFICATIONS |
|
416 |
|
417 // if allocation should fail, threshold should not naturally be set |
|
418 if (!iMemAllocationsGrowing) |
|
419 { |
|
420 TRAP_IGNORE(iMemAllocationsGrowing = CreateThresholdCrossedThreadL(*this, EGL_PROF_TOTAL_MEMORY_USAGE_GT_NOK, iLowThreshold)) |
|
421 origLow = iLowThreshold; // do not reset |
|
422 } |
|
423 if (!iMemAllocationsGoingDown) |
|
424 { |
|
425 TRAP_IGNORE(iMemAllocationsGoingDown = CreateThresholdCrossedThreadL(*this, EGL_PROF_TOTAL_MEMORY_USAGE_LT_NOK, iGoodThreshold)) |
|
426 origGood = iGoodThreshold; // do not reset |
|
427 } |
|
428 |
|
429 TBool releaseClient = ETrue; |
|
430 |
|
431 // update thresholds only if they really change |
|
432 if (origGood != iGoodThreshold) |
|
433 { |
|
434 iMemAllocationsGoingDown->SetThreshold(iGoodThreshold); |
|
435 } |
|
436 |
|
437 if ( origLow != iLowThreshold) |
|
438 { |
|
439 // need to synchronously check whether client should wait |
|
440 // memory to be released |
|
441 if(GetFreeMemory() <= iLowThreshold ) |
|
442 { |
|
443 releaseClient = EFalse; |
|
444 } |
|
445 iMemAllocationsGrowing->SetThreshold(iLowThreshold); |
|
446 } |
|
447 |
|
448 TRACES3("CMemoryMonitor::RefreshThresholds: releaseClient: %d For foreground app 0x%x, Active client = 0x%x",releaseClient, aForegroundAppUid, ActiveClientId()); |
|
449 |
|
450 if (releaseClient && ActiveClientId() == iForegroundAppUid) |
|
451 { |
|
452 iServer->CloseAppsFinished(0, ETrue); |
|
453 } |
|
454 #endif |
|
455 |
|
456 TRACES2("CMemoryMonitor::RefreshThresholds: Current Good Threshold = %d, Current Low Threshold = %d", iGoodThreshold, iLowThreshold); |
|
457 } |
|
458 |
|
459 void CMemoryMonitor::ResetTargets(TInt aTarget) |
|
460 { |
|
461 FUNC_LOG; |
|
462 |
|
463 //we reset the target when a memory free operation completes, to deal with the case |
|
464 //where the operation was initiated with a target larger than the current good threshold |
|
465 iCurrentTarget = aTarget; |
|
466 iGOomActionList->SetCurrentTarget(iCurrentTarget); |
|
467 } |
|
468 |
|
469 void CMemoryMonitor::SetPriorityBusy(TInt aWgId) |
|
470 { |
|
471 FUNC_LOG; |
|
472 |
|
473 TRACES2("Received SetPriorityBusy for appid = %x, wgid = %d", iGOomWindowGroupList->AppIdfromWgId(aWgId, ETrue), aWgId); |
|
474 iGOomWindowGroupList->SetPriorityBusy(aWgId); |
|
475 AppClosePriorityChanged(aWgId, RGOomMonitorSession::EGOomPriorityBusy); |
|
476 } |
|
477 |
|
478 void CMemoryMonitor::SetPriorityNormal(TInt aWgId) |
|
479 { |
|
480 FUNC_LOG; |
|
481 |
|
482 iGOomWindowGroupList->SetPriorityNormal(aWgId); |
|
483 AppClosePriorityChanged(aWgId, RGOomMonitorSession::EGOomPriorityNormal); |
|
484 } |
|
485 |
|
486 void CMemoryMonitor::SetPriorityHigh(TInt aWgId) |
|
487 { |
|
488 FUNC_LOG; |
|
489 |
|
490 iGOomWindowGroupList->SetPriorityHigh(aWgId); |
|
491 AppClosePriorityChanged(aWgId, RGOomMonitorSession::EGOomPriorityHigh); |
|
492 } |
|
493 |
|
494 TInt CMemoryMonitor::GetFreeMemory() |
|
495 { |
|
496 FUNC_LOG; |
|
497 if (!eglQueryProfilingData) |
|
498 { |
|
499 TRACES("EGL_NOK_resource_profiling not available"); |
|
500 return 0; |
|
501 } |
|
502 EGLint data_count; |
|
503 EGLint* prof_data; |
|
504 TInt i(0); |
|
505 TInt totalMem(0); |
|
506 TInt totalUsed(0); |
|
507 EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
|
508 |
|
509 /* Find out how much profiling data is available */ |
|
510 eglQueryProfilingData(dpy, EGL_PROF_QUERY_GLOBAL_BIT_NOK | EGL_PROF_QUERY_MEMORY_USAGE_BIT_NOK, |
|
511 NULL, 0, &data_count); |
|
512 |
|
513 TRACES1("eglQueryProfilingData - data size: %d", data_count); |
|
514 |
|
515 |
|
516 /* Allocate room for the profiling data */ |
|
517 prof_data = (EGLint*)User::Alloc(data_count * sizeof(EGLint)); |
|
518 if (prof_data == NULL) |
|
519 { |
|
520 TRACES1("eglQueryProfilingData - could not alloc: %d", data_count * sizeof(EGLint)); |
|
521 return KErrNoMemory; |
|
522 } |
|
523 |
|
524 /* Retrieve the profiling data */ |
|
525 eglQueryProfilingData(dpy, |
|
526 EGL_PROF_QUERY_GLOBAL_BIT_NOK | |
|
527 EGL_PROF_QUERY_MEMORY_USAGE_BIT_NOK, |
|
528 prof_data, |
|
529 data_count, |
|
530 &data_count); |
|
531 |
|
532 /* Iterate over the returned data */ |
|
533 while (i < data_count) |
|
534 { |
|
535 TRACES2("EGL_NOK_resource_profiling - index: %d data: %d", i, prof_data[i]); |
|
536 |
|
537 switch (prof_data[i++]) |
|
538 { |
|
539 case EGL_PROF_USED_MEMORY_NOK: |
|
540 { |
|
541 totalUsed = prof_data[i++]; |
|
542 TRACES1("EGL_NOK_resource_profiling - total Used: %d", totalUsed); |
|
543 |
|
544 break; |
|
545 } |
|
546 case EGL_PROF_TOTAL_MEMORY_NOK: |
|
547 { |
|
548 totalMem = prof_data[i++]; |
|
549 TRACES1("EGL_NOK_resource_profiling - total Mem: %d", totalMem); |
|
550 break; |
|
551 } |
|
552 case EGL_PROF_PROCESS_ID_NOK: |
|
553 { |
|
554 if (sizeof(EGLNativeProcessIdTypeNOK) == 8) |
|
555 { |
|
556 i+=2; |
|
557 } |
|
558 else |
|
559 { |
|
560 i++; |
|
561 } |
|
562 break; |
|
563 } |
|
564 case EGL_PROF_PROCESS_USED_PRIVATE_MEMORY_NOK: |
|
565 case EGL_PROF_PROCESS_USED_SHARED_MEMORY_NOK: |
|
566 default: |
|
567 { |
|
568 i++; |
|
569 break; |
|
570 } |
|
571 } |
|
572 } |
|
573 |
|
574 /* Free allocated memory */ |
|
575 User::Free(prof_data); |
|
576 |
|
577 |
|
578 if ((totalMem-totalUsed) < 0) |
|
579 { |
|
580 return 0; |
|
581 } |
|
582 return totalMem - totalUsed; |
|
583 } |
|
584 |
|
585 void CMemoryMonitor::DoPostponedMemoryGood() |
|
586 { |
|
587 FUNC_LOG; |
|
588 TInt current = GetFreeMemory(); |
|
589 if(current >= iGoodThreshold && (!NeedToPostponeMemGood())) |
|
590 { |
|
591 TRACES("DoPostponedMemoryGood calling MemoryGOOD"); |
|
592 iGOomActionList->MemoryGood(); |
|
593 } |
|
594 } |
|
595 |
|
596 |
|
597 void CMemoryMonitor::AppClosePriorityChanged(TInt aWgId, TInt aPriority) |
|
598 { |
|
599 FUNC_LOG; |
|
600 CGOomCloseAppConfig* appCloseConfig = NULL; |
|
601 |
|
602 TRACES1("CMemoryMonitor::AppClosePriorityChanged wgid %d", aWgId); |
|
603 |
|
604 switch(aPriority) |
|
605 { |
|
606 case RGOomMonitorSession::EGOomPriorityBusy: |
|
607 appCloseConfig = iConfig->GetApplicationConfig(KGOomBusyAppId).GetAppCloseConfig(); |
|
608 TRACES("CMemoryMonitor::AppClosePriorityChanged BUSY"); |
|
609 break; |
|
610 case RGOomMonitorSession::EGOomPriorityHigh: |
|
611 appCloseConfig = iConfig->GetApplicationConfig(KGOomHighPriorityAppId).GetAppCloseConfig(); |
|
612 TRACES("CMemoryMonitor::AppClosePriorityChanged HIGH"); |
|
613 break; |
|
614 default: |
|
615 appCloseConfig = iConfig->GetApplicationConfig(aWgId).GetAppCloseConfig(); |
|
616 TRACES("CMemoryMonitor::AppClosePriorityChanged NORMAL"); |
|
617 } |
|
618 |
|
619 if (appCloseConfig) |
|
620 { |
|
621 TInt32 appId = iGOomWindowGroupList->AppIdfromWgId(aWgId, ETrue); |
|
622 TInt wgIndex=iGOomWindowGroupList->GetIndexFromAppId(appId); |
|
623 |
|
624 TRACES2("CMemoryMonitor::AppClosePriorityChanged wgindex %d, appid %x", wgIndex, appId); |
|
625 |
|
626 if(wgIndex>=0) |
|
627 { |
|
628 TRACES2("CMemoryMonitor::AppClosePriorityChanged Setting Priority for app %x, wgid %d", appId, aWgId); |
|
629 TUint priority = appCloseConfig->CalculateCloseAppPriority(*iGOomWindowGroupList, wgIndex); |
|
630 iGOomActionList->SetPriority(wgIndex, priority); |
|
631 } |
|
632 else |
|
633 { |
|
634 TRACES1("CMemoryMonitor::AppClosePriorityChanged Could not find wgid %d in windogouplist", aWgId); |
|
635 } |
|
636 } |
|
637 else |
|
638 { |
|
639 TRACES("CMemoryMonitor::AppClosePriorityChanged appCloseConfig not found"); |
|
640 } |
|
641 } |
|
642 |
|
643 CGOomWindowGroupList * CMemoryMonitor::GetWindowGroupList() const |
|
644 { |
|
645 return iGOomWindowGroupList; |
|
646 } |