userlibandfileserver/fileserver/sfile/sf_cache_man.cpp
changeset 297 b2826f67641f
parent 176 af6ec97d9189
equal deleted inserted replaced
296:94f2adf59133 297:b2826f67641f
    40 
    40 
    41 #ifdef __RAMDOM_LOCK_FAILURES__	
    41 #ifdef __RAMDOM_LOCK_FAILURES__	
    42 #include <e32math.h>
    42 #include <e32math.h>
    43 #endif
    43 #endif
    44 
    44 
       
    45 #ifdef OST_TRACE_COMPILER_IN_USE
       
    46 #include "sf_cache_manTraces.h"
       
    47 #endif
       
    48 
    45 #define CACHE_NUM_TO_ADDR(n) (iBase + (n << iCacheLineSizeLog2))
    49 #define CACHE_NUM_TO_ADDR(n) (iBase + (n << iCacheLineSizeLog2))
    46 #define ADDR_TO_CACHELINE_ADDR(a) ((((a - iBase) >> iCacheLineSizeLog2) << iCacheLineSizeLog2) + iBase)
    50 #define ADDR_TO_CACHELINE_ADDR(a) ((((a - iBase) >> iCacheLineSizeLog2) << iCacheLineSizeLog2) + iBase)
    47 #define ADDR_TO_INDEX(a) ((a - iBase) >> iCacheLineSizeLog2)
    51 #define ADDR_TO_INDEX(a) ((a - iBase) >> iCacheLineSizeLog2)
    48 
    52 
    49 #if defined(_DEBUG)
    53 #if defined(_DEBUG)
   187 	// calculate the low-memory threshold below which we fail any attempt to allocate memory
   191 	// calculate the low-memory threshold below which we fail any attempt to allocate memory
   188 	TMemoryInfoV1Buf meminfo;
   192 	TMemoryInfoV1Buf meminfo;
   189 	TInt r = UserHal::MemoryInfo(meminfo);
   193 	TInt r = UserHal::MemoryInfo(meminfo);
   190 	__ASSERT_ALWAYS(r==KErrNone,Fault(EMemoryInfoFailed));
   194 	__ASSERT_ALWAYS(r==KErrNone,Fault(EMemoryInfoFailed));
   191 
   195 
   192 	iLowMemoryThreshold = (meminfo().iTotalRamInBytes * TGlobalFileCacheSettings::LowMemoryThreshold()) / 100;
   196 	iLowMemoryThreshold = (meminfo().iTotalRamInBytes  / 100) * TGlobalFileCacheSettings::LowMemoryThreshold();
   193 	__CACHE_PRINT4(_L("CACHEMAN: totalRAM %d freeRAM %d KDefaultLowMemoryThresholdPercent %d iLowMemoryThreshold %d"), 
   197 	__CACHE_PRINT4(_L("CACHEMAN: totalRAM %d freeRAM %d KDefaultLowMemoryThresholdPercent %d iLowMemoryThreshold %d"), 
   194 		meminfo().iTotalRamInBytes, meminfo().iFreeRamInBytes, KDefaultLowMemoryThreshold, iLowMemoryThreshold);
   198 		meminfo().iTotalRamInBytes, meminfo().iFreeRamInBytes, KDefaultLowMemoryThreshold, iLowMemoryThreshold);
   195 	__CACHE_PRINT1(_L("CACHEMAN: iCacheSize %d"), iCacheSize);
   199 	__CACHE_PRINT1(_L("CACHEMAN: iCacheSize %d"), iCacheSize);
   196 	TChunkCreateInfo createInfo;
   200 	TChunkCreateInfo createInfo;
   197 	createInfo.SetCache(iCacheSize);
   201 	createInfo.SetCache(iCacheSize);
   198 	createInfo.SetOwner(EOwnerProcess);
   202 	createInfo.SetOwner(EOwnerProcess);
   199 	r = iChunk.Create(createInfo);
   203 	r = iChunk.Create(createInfo);
   200 	User::LeaveIfError(r);
   204 	User::LeaveIfError(r);
   201 
   205 
       
   206 #ifdef	OST_TRACE_COMPILER_IN_USE
       
   207 	TName chunkName = iChunk.Name();
       
   208 	OstTraceData(TRACE_FILECACHE_MANAGER, FILECACHEMAN_CHUNK_NAME, "Chunk name %S", chunkName.Ptr(), chunkName.Length()<<1);
       
   209 	OstTraceExt5(TRACE_FILECACHE_MANAGER, FILECACHEMAN_CHUNK_PARM, 
       
   210 		"totalRAM %d freeRAM %d KDefaultLowMemoryThresholdPercent %d iLowMemoryThreshold %d iCacheSize %d", 
       
   211 		meminfo().iTotalRamInBytes, meminfo().iFreeRamInBytes, KDefaultLowMemoryThreshold, iLowMemoryThreshold, iCacheSize);
       
   212 #endif	// OST_TRACE_COMPILER_IN_USE
   202 	
   213 	
   203 	TInt mm = UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, 0, 0) & EMemModelTypeMask;
   214 	TInt mm = UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, 0, 0) & EMemModelTypeMask;
   204 	if (mm < EMemModelTypeFlexible)
   215 	if (mm < EMemModelTypeFlexible)
   205 		{
   216 		{
   206 		// On memory models before flexible, File System has to register chunks that will be DMA-ed.
   217 		// On memory models before flexible, File System has to register chunks that will be DMA-ed.
   307 TFileCacheStats& CCacheManager::Stats()
   318 TFileCacheStats& CCacheManager::Stats()
   308 	{
   319 	{
   309 	iStats.iFreeCount = iFreeQueue.Count();
   320 	iStats.iFreeCount = iFreeQueue.Count();
   310 	iStats.iUsedCount = iUsedQueue.Count();
   321 	iStats.iUsedCount = iUsedQueue.Count();
   311 	iStats.iLockedSegmentCount = iLockedSegmentCount;
   322 	iStats.iLockedSegmentCount = iLockedSegmentCount;
       
   323 	iStats.iAllocatedSegmentCount = iAllocatedSegmentCount;
   312 	iStats.iFilesOnClosedQueue = TClosedFileUtils::Count();
   324 	iStats.iFilesOnClosedQueue = TClosedFileUtils::Count();
   313 	__ASSERT_DEBUG(iStats.iFreeCount >= 0, Fault(EInvalidStats));
   325 	__ASSERT_DEBUG(iStats.iFreeCount >= 0, Fault(EInvalidStats));
   314 	__ASSERT_DEBUG(iStats.iUsedCount >= 0, Fault(EInvalidStats));
   326 	__ASSERT_DEBUG(iStats.iUsedCount >= 0, Fault(EInvalidStats));
   315 	__ASSERT_DEBUG(iStats.iLockedSegmentCount >= 0, Fault(EInvalidStats));
   327 	__ASSERT_DEBUG(iStats.iLockedSegmentCount >= 0, Fault(EInvalidStats));
   316 	__ASSERT_DEBUG(iStats.iFilesOnClosedQueue >= 0, Fault(EInvalidStats));
   328 	__ASSERT_DEBUG(iStats.iFilesOnClosedQueue >= 0, Fault(EInvalidStats));
   347 	TInt r = UserHal::MemoryInfo(meminfo);
   359 	TInt r = UserHal::MemoryInfo(meminfo);
   348 	__ASSERT_ALWAYS(r==KErrNone,Fault(EMemoryInfoFailed));
   360 	__ASSERT_ALWAYS(r==KErrNone,Fault(EMemoryInfoFailed));
   349 	if (iMemoryLow || (meminfo().iFreeRamInBytes < iLowMemoryThreshold))
   361 	if (iMemoryLow || (meminfo().iFreeRamInBytes < iLowMemoryThreshold))
   350 		{
   362 		{
   351 		__CACHE_PRINT(_L("CACHEMAN: free RAM below threshold !!!"));
   363 		__CACHE_PRINT(_L("CACHEMAN: free RAM below threshold !!!"));
       
   364 		OstTrace0(TRACE_FILECACHE_MANAGER, FILECACHEMAN_LOW_MEM, "Free RAM below threshold");
   352 		return KErrNoMemory;
   365 		return KErrNoMemory;
   353 		}
   366 		}
   354 
   367 
   355 	CacheLock();
   368 	CacheLock();
   356 
   369 
   359 
   372 
   360 #ifdef  __SIMULATE_LOCK_FAILURES__
   373 #ifdef  __SIMULATE_LOCK_FAILURES__
   361 	if (SimulatedFailure(iAllocFailureCount))
   374 	if (SimulatedFailure(iAllocFailureCount))
   362 		{
   375 		{
   363 		__CACHE_PRINT(_L("CACHEMAN: simulating allocation failure"));
   376 		__CACHE_PRINT(_L("CACHEMAN: simulating allocation failure"));
       
   377 		OstTrace0(TRACE_FILECACHE_MANAGER, FILECACHEMAN_SIMULATING_ALLOC_FAILURE, "Simulating alloc failure");
       
   378 
   364 		CacheUnlock();
   379 		CacheUnlock();
   365 		return KErrNoMemory;
   380 		return KErrNoMemory;
   366 		}
   381 		}
   367 #endif
   382 #endif
   368 
   383 
   411 	cacheLine->iClient = aClient;
   426 	cacheLine->iClient = aClient;
   412 	cacheLine->iPos = aPos;
   427 	cacheLine->iPos = aPos;
   413 
   428 
   414 	// Remove from free queue
   429 	// Remove from free queue
   415 	iFreeQueue.Remove(0);
   430 	iFreeQueue.Remove(0);
       
   431 
       
   432 	OstTraceExt2(TRACE_FILECACHE_MANAGER, FILECACHEMAN_ALLOC_CACHELINE, "cachelines: free %d used %d", iFreeQueue.Count(), iUsedQueue.Count());
   416 
   433 
   417 	// RChunk will lock segments initially unless explicitly unlocked
   434 	// RChunk will lock segments initially unless explicitly unlocked
   418 
   435 
   419 	cacheLine->iLockCount++;
   436 	cacheLine->iLockCount++;
   420 	
   437 	
   903 //	TInt r = iFreeQueue.Append(&aCacheLine);
   920 //	TInt r = iFreeQueue.Append(&aCacheLine);
   904 	TInt r = iFreeQueue.InsertInAddressOrder(&aCacheLine);
   921 	TInt r = iFreeQueue.InsertInAddressOrder(&aCacheLine);
   905 	__ASSERT_ALWAYS(r == KErrNone, Fault(EAppendToFreeQueueFailed));
   922 	__ASSERT_ALWAYS(r == KErrNone, Fault(EAppendToFreeQueueFailed));
   906 
   923 
   907 	__CACHE_PRINT2(_L("CACHEMAN: FreeCacheLine, iFreeQueue %d iUsedQueue %d"), iFreeQueue.Count(), iUsedQueue.Count());
   924 	__CACHE_PRINT2(_L("CACHEMAN: FreeCacheLine, iFreeQueue %d iUsedQueue %d"), iFreeQueue.Count(), iUsedQueue.Count());
       
   925 	OstTraceExt2(TRACE_FILECACHE_MANAGER, FILECACHEMAN_FREE_CACHELINE, "cachelines: free %d used %d", iFreeQueue.Count(), iUsedQueue.Count());
   908 	}
   926 	}
   909 
   927 
   910 
   928 
   911 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
   929 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
   912 void CCacheManager::DumpCacheLine(TCacheLine& aCacheLine)
   930 void CCacheManager::DumpCacheLine(TCacheLine& aCacheLine)
   982 
  1000 
   983 #ifdef  __SIMULATE_LOCK_FAILURES__
  1001 #ifdef  __SIMULATE_LOCK_FAILURES__
   984 	if (SimulatedFailure(iLockFailureCount))
  1002 	if (SimulatedFailure(iLockFailureCount))
   985 		{
  1003 		{
   986 		__CACHE_PRINT(_L("CACHEMAN: simulating lock failure"));
  1004 		__CACHE_PRINT(_L("CACHEMAN: simulating lock failure"));
       
  1005 		OstTrace0(TRACE_FILECACHE_MANAGER, FILECACHEMAN_SIMULATING_LOCK_FAILURE, "Simulating lock failure");
       
  1006 
   987 		r = KErrNotFound;
  1007 		r = KErrNotFound;
   988 		}
  1008 		}
   989 #endif
  1009 #endif
   990 
  1010 
   991 	if (r == KErrNone)
  1011 	if (r == KErrNone)
   992 		{
  1012 		{
   993 		iLockedSegmentCount+= aSegmentCount;
  1013 		iLockedSegmentCount+= aSegmentCount;
       
  1014 
       
  1015 		OstTrace1(TRACE_FILECACHE_MANAGER, FILECACHEMAN_LOCK_SEGMENTS, "Locked segments %d", iLockedSegmentCount);
   994 		}
  1016 		}
   995 	else
  1017 	else
   996 		{
  1018 		{
   997 		__CACHE_PRINT(_L("CACHEMAN: LOCK FAILED"));
  1019 		__CACHE_PRINT(_L("CACHEMAN: LOCK FAILED"));
       
  1020 		OstTrace1(TRACE_FILECACHE_MANAGER, FILECACHEMAN_LOCK_FAILURE, "Failure r %d", r);
       
  1021 
   998 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1022 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
   999 		iStats.iLockFailureCount++;
  1023 		iStats.iLockFailureCount++;
  1000 #endif
  1024 #endif
  1001 		}
  1025 		}
  1002 
  1026 
  1010 
  1034 
  1011 	__CACHE_PRINT3(_L("CACHEMAN: UNLOCK %08X %d %d"), aAddr, aSegmentCount, r);
  1035 	__CACHE_PRINT3(_L("CACHEMAN: UNLOCK %08X %d %d"), aAddr, aSegmentCount, r);
  1012 	if (r == KErrNone)
  1036 	if (r == KErrNone)
  1013 		{
  1037 		{
  1014 		iLockedSegmentCount-= aSegmentCount;
  1038 		iLockedSegmentCount-= aSegmentCount;
       
  1039 
       
  1040 		OstTrace1(TRACE_FILECACHE_MANAGER, FILECACHEMAN_UNLOCK_SEGMENTS, "Locked segments %d", iLockedSegmentCount);
  1015 		}
  1041 		}
  1016 	else
  1042 	else
  1017 		{
  1043 		{
  1018 		__CACHE_PRINT(_L("CACHEMAN: UNLOCK FAILED"));
  1044 		__CACHE_PRINT(_L("CACHEMAN: UNLOCK FAILED"));
  1019 		}
  1045 		}
  1025 	{
  1051 	{
  1026 #ifdef  __SIMULATE_LOCK_FAILURES__
  1052 #ifdef  __SIMULATE_LOCK_FAILURES__
  1027 	if (SimulatedFailure(iCommitFailureCount))
  1053 	if (SimulatedFailure(iCommitFailureCount))
  1028 		{
  1054 		{
  1029 		__CACHE_PRINT(_L("CACHEMAN: simulating commit failure "));
  1055 		__CACHE_PRINT(_L("CACHEMAN: simulating commit failure "));
       
  1056 		OstTrace0(TRACE_FILECACHE_MANAGER, FILECACHEMAN_SIMULATING_COMMIT_FAILURE, "Simulating commit failure");
       
  1057 
  1030 		return KErrNoMemory;
  1058 		return KErrNoMemory;
  1031 		}
  1059 		}
  1032 #endif
  1060 #endif
  1033 
  1061 
  1034 	TInt r = iChunk.Commit(aAddr-iBase, aSegmentCount << KSegmentSizeLog2);
  1062 	TInt r = iChunk.Commit(aAddr-iBase, aSegmentCount << KSegmentSizeLog2);
  1036 	
  1064 	
  1037 	__CACHE_PRINT3(_L("CACHEMAN: COMMIT: %08X %d %d, "), aAddr, aSegmentCount, r);
  1065 	__CACHE_PRINT3(_L("CACHEMAN: COMMIT: %08X %d %d, "), aAddr, aSegmentCount, r);
  1038 	if (r == KErrNone)
  1066 	if (r == KErrNone)
  1039 		{
  1067 		{
  1040 		iLockedSegmentCount+= aSegmentCount;
  1068 		iLockedSegmentCount+= aSegmentCount;
  1041 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1069 		iAllocatedSegmentCount+= aSegmentCount;
  1042 		iStats.iAllocatedSegmentCount+= aSegmentCount;
  1070 
  1043 #endif
  1071 		OstTrace1(TRACE_FILECACHE_MANAGER, FILECACHEMAN_COMMIT_SEGMENTS, "Allocated segments %d", iAllocatedSegmentCount);
  1044 		}
  1072 		}
  1045 	else
  1073 	else
  1046 		{
  1074 		{
  1047 		__CACHE_PRINT(_L("CACHEMAN: COMMIT FAILED"));
  1075 		__CACHE_PRINT(_L("CACHEMAN: COMMIT FAILED"));
       
  1076 		OstTrace1(TRACE_FILECACHE_MANAGER, FILECACHEMAN_COMMIT_FAILURE, "Failure r %d", r);
       
  1077 
  1048 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1078 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1049 		iStats.iCommitFailureCount++;
  1079 		iStats.iCommitFailureCount++;
  1050 #endif
  1080 #endif
  1051 		}
  1081 		}
  1052 
  1082 
  1062 //RDebug::Print(_L("RChunk::Decommit(%08X, %d), %d"), aAddr-iBase, aSegmentCount << KSegmentSizeLog2, r);
  1092 //RDebug::Print(_L("RChunk::Decommit(%08X, %d), %d"), aAddr-iBase, aSegmentCount << KSegmentSizeLog2, r);
  1063 
  1093 
  1064 	__CACHE_PRINT3(_L("CACHEMAN: DECOMMIT: %08X %d %d, "), aAddr, aSegmentCount, r);
  1094 	__CACHE_PRINT3(_L("CACHEMAN: DECOMMIT: %08X %d %d, "), aAddr, aSegmentCount, r);
  1065 	if (r == KErrNone)
  1095 	if (r == KErrNone)
  1066 		{
  1096 		{
       
  1097 		iAllocatedSegmentCount-= aSegmentCount;
       
  1098 
       
  1099 		OstTrace1(TRACE_FILECACHE_MANAGER, FILECACHEMAN_DECOMMIT_SEGMENTS, "Allocated segments %d", iAllocatedSegmentCount);
       
  1100 		}
       
  1101 	else
       
  1102 		{
       
  1103 		__CACHE_PRINT(_L("CACHEMAN: DECOMMIT FAILED"));
       
  1104 		}
       
  1105 
       
  1106 	return r;
       
  1107 	}
       
  1108 
  1067 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1109 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1068 		iStats.iAllocatedSegmentCount-= aSegmentCount;
       
  1069 #endif
       
  1070 		}
       
  1071 	else
       
  1072 		{
       
  1073 		__CACHE_PRINT(_L("CACHEMAN: DECOMMIT FAILED"));
       
  1074 		}
       
  1075 
       
  1076 	return r;
       
  1077 	}
       
  1078 
       
  1079 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
  1080 
  1110 
  1081 void CCacheManager::SimulateLockFailureMode(TBool aEnable)
  1111 void CCacheManager::SimulateLockFailureMode(TBool aEnable)
  1082 	{
  1112 	{
  1083 	iSimulateLockFailureMode = aEnable;
  1113 	iSimulateLockFailureMode = aEnable;
  1084 __CACHE_PRINT1(_L("CACHEMAN: SimulateLockFailureMode: %d, "), iSimulateLockFailureMode);
  1114 
       
  1115 	__CACHE_PRINT1(_L("CACHEMAN: SimulateLockFailureMode: %d, "), iSimulateLockFailureMode);
       
  1116 	OstTrace1(TRACE_FILECACHE_MANAGER, FILECACHEMAN_SIMULATE_LOCK_FAILURE_MODE, "aEnable %d", aEnable);
  1085 	}
  1117 	}
  1086 
  1118 
  1087 void CCacheManager::AllocateMaxSegments(TBool aEnable)
  1119 void CCacheManager::AllocateMaxSegments(TBool aEnable)
  1088 	{
  1120 	{
  1089 	iAllocateMaxSegments = aEnable;
  1121 	iAllocateMaxSegments = aEnable;
  1090 __CACHE_PRINT1(_L("CACHEMAN: iAllocateMaxSegments: %d, "), iAllocateMaxSegments);
  1122 	__CACHE_PRINT1(_L("CACHEMAN: iAllocateMaxSegments: %d, "), iAllocateMaxSegments);
  1091 	}
  1123 	}
  1092 
  1124 
  1093 TBool CCacheManager::AllocateMaxSegments()
  1125 TBool CCacheManager::AllocateMaxSegments()
  1094 	{
  1126 	{
  1095 	return iAllocateMaxSegments;
  1127 	return iAllocateMaxSegments;