sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // f32\sfile\sf_cache_man.h sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #if !defined(__SF_CACHE_MAN_H__) sl@0: #define __SF_CACHE_MAN_H__ sl@0: sl@0: #ifdef _DEBUG sl@0: #define __SIMULATE_LOCK_FAILURES__ sl@0: #endif sl@0: sl@0: // forward ref sl@0: class CCacheManager; sl@0: class CCacheClient; sl@0: sl@0: const TInt KByteToByteShift = 10; sl@0: sl@0: enum TCacheManagerFault sl@0: { sl@0: ENoCacheManager = 0, sl@0: ECacheAlreadyCreated = 1, sl@0: EIllegalDriveNumber = 2, sl@0: EIllegalCacheSize = 3, sl@0: EIllegalPageSize = 4, sl@0: EInvalidAllocCount = 5, sl@0: EInvalidLockCount = 6, sl@0: EInvalidFillCount = 7, sl@0: EAppendToFreeQueueFailed = 8, sl@0: ESegmentNotFound = 9, sl@0: EUnlockFailed = 10, sl@0: EInvalidSegmentCount = 11, sl@0: EInvalidAddress = 12, sl@0: EInvalidDirtyCount = 13, sl@0: EDecommitFailed = 14, sl@0: EUnexpectedCommitFailure = 15, sl@0: EUnexpectedLockFailure = 16, sl@0: EInvalidCacheLine = 17, sl@0: EInvalidClient = 18, sl@0: ERemovingEmptyUnlocked = 19, sl@0: EFreeingLockedCacheLine = 20, sl@0: EFreeingDirtyCacheLine = 21, sl@0: ESetDirtyNotLocked = 22, sl@0: EClearDirtyNotLocked = 23, sl@0: ESetFilledNotLocked = 24, sl@0: EManagerNotLocked = 25, sl@0: EExtendingUnownedCacheline = 26, sl@0: EUnlockingUnownedCacheline = 27, sl@0: EInvalidLockedPageStart = 28, sl@0: EInvalidLockedPageCount = 29, sl@0: EInvalidLockRange = 30, sl@0: ESetDirtyInvalidLockRange = 31, sl@0: ELockingAndAlreadyDirty = 32, sl@0: EInvalidStats = 33 sl@0: }; sl@0: sl@0: sl@0: class CCacheManagerFactory sl@0: { sl@0: public: sl@0: static void CreateL(); sl@0: static TInt Destroy(); sl@0: static CCacheManager* CacheManager(); sl@0: private: sl@0: static CCacheManager* iCacheManager; sl@0: }; sl@0: sl@0: sl@0: NONSHARABLE_CLASS(CCacheManager) : public CBase sl@0: { sl@0: private: sl@0: sl@0: class TCacheLine sl@0: { sl@0: public: sl@0: TUint8* iAddr; sl@0: TUint8 iAllocatedSegments; // number of allocated pages sl@0: TUint8 iFilledSegments; // number of full pages (i.e. pages with data in) sl@0: TUint8 iDirtySegments; // number of dirty pages sl@0: TUint8 iLockCount; // number of times cacheline has been locked sl@0: TUint8 iLockedSegmentStart; // zero based index of first locked paged sl@0: TUint8 iLockedSegmentCount; // number of locked pages sl@0: TUint8 iSpare[2]; // padding sl@0: CCacheClient* iClient; // owner of this cacheline sl@0: TInt64 iPos; // arbitrary data owned by client sl@0: }; sl@0: sl@0: public: sl@0: CCacheClient* CreateClientL(); sl@0: void RegisterClient(CCacheClient& aClient); sl@0: void DeregisterClient(CCacheClient& aClient); sl@0: sl@0: sl@0: TInt SegmentSize(); sl@0: TInt SegmentSizeLog2(); sl@0: TInt64 SegmentSizeMask(); sl@0: TInt CacheLineSize(); sl@0: TInt CacheLineSizeLog2(); sl@0: TInt CacheLineSizeInSegments(); sl@0: sl@0: // called from CCacheClient sl@0: TInt AllocateAndLockCacheLine(CCacheClient* aClient, TInt64 aPos, const TCacheLine*& aCacheLine, TInt aSegmentCount); sl@0: TInt ReAllocateAndLockCacheLine(CCacheClient* aClient, TInt64 aPos, const TCacheLine& aCacheLine, TInt aSegmentCount); sl@0: sl@0: TInt ExtendCacheLine(CCacheClient* aClient, const TCacheLine& aCacheLine, TInt aSegmentCount); sl@0: void RemoveEmptySegments(CCacheClient* aClient, const TCacheLine& aCacheLine); sl@0: sl@0: TInt LockCacheLine(CCacheClient* aClient, const TCacheLine& aCacheLine, TInt aLockedPageStart, TInt aLockedPageCount); sl@0: TBool UnlockCacheLine(CCacheClient* aClient, const TCacheLine& aCacheLine); sl@0: sl@0: TBool FreeCacheLine(CCacheClient* aClient, const TCacheLine& aCacheLine); sl@0: sl@0: sl@0: TInt LockCount(CCacheClient* aClient, const TCacheLine& aCacheLine); sl@0: TInt FillCount(CCacheClient* aClient, const TCacheLine& aCacheLine); sl@0: TInt DirtyCount(CCacheClient* aClient, const TCacheLine& aCacheLine); sl@0: TBool TooManyLockedSegments(); sl@0: sl@0: void SetFilled(CCacheClient* aClient, const TCacheLine& aCacheLine, TInt aSegmentCount); sl@0: void SetDirty(CCacheClient* aClient, const TCacheLine& aCacheLine, TInt aSegmentCount); sl@0: void ClearDirty(CCacheClient* aClient, const TCacheLine& aCacheLine); sl@0: TBool InUse(const TCacheLine& aCacheLine); sl@0: sl@0: // called from CKernEventNotifier::FreeMemoryChangeCallback() sl@0: void FreeMemoryChanged(TBool aMemoryLow); sl@0: sl@0: #if defined(_DEBUG) || defined(_DEBUG_RELEASE) sl@0: void DumpCache(); sl@0: void DumpCacheLine(TCacheLine& aCacheLine); sl@0: void SimulateLockFailureMode(TBool aEnable); sl@0: void AllocateMaxSegments(TBool aEnable); sl@0: TBool AllocateMaxSegments(); sl@0: // stats sl@0: TFileCacheStats& Stats(); sl@0: sl@0: void SimulateWriteFailure(); sl@0: TBool SimulateWriteFailureEnabled(); sl@0: TBool SimulatedFailure(TInt& aFailureCount); sl@0: #endif sl@0: sl@0: private: sl@0: ~CCacheManager(); sl@0: sl@0: CCacheManager(TUint aCacheSize); sl@0: void ConstructL(); sl@0: sl@0: inline TUint8* Base(); sl@0: sl@0: inline void CacheLock(); sl@0: inline void CacheUnlock(); sl@0: sl@0: TBool StealCacheLine(CCacheClient* aClient); sl@0: sl@0: TInt Lock(TUint8* aAddr, TInt aSegmentCount); sl@0: TInt Unlock(TUint8* aAddr, TInt aSegmentCount); sl@0: TInt Commit(TUint8* aAddr, TInt aSegmentCount); sl@0: TInt Decommit(TUint8* aAddr, TInt aSegmentCount); sl@0: sl@0: static CCacheManager* NewCacheL(TInt aUncommitedCacheSize); sl@0: sl@0: void FreeCacheLine(TCacheLine& aCacheLine); sl@0: sl@0: private: sl@0: sl@0: RFastLock iLock; sl@0: sl@0: TCacheLine* iCacheLines; sl@0: RPointerArray iFreeQueue; sl@0: RPointerArray iUsedQueue; sl@0: sl@0: TUint8* iBase; sl@0: sl@0: TInt iNumOfCacheLines; sl@0: sl@0: TInt iCacheLineSize; sl@0: TInt iCacheLineSizeLog2; sl@0: sl@0: TInt iCacheSize; sl@0: TInt iMaxLockedSegments; sl@0: sl@0: TInt iSegmentsPerCacheLine; sl@0: sl@0: TInt iLockedSegmentCount; sl@0: sl@0: RChunk iChunk; sl@0: TBool iSimulateLockFailureMode; sl@0: sl@0: #if defined(_DEBUG) || defined(_DEBUG_RELEASE) sl@0: TBool iManagerLocked; sl@0: TInt iLockFailureCount; sl@0: TInt iCommitFailureCount; sl@0: TInt iAllocFailureCount; sl@0: TBool iAllocateMaxSegments; sl@0: sl@0: TFileCacheStats iStats; sl@0: TBool iSimulateWriteFailure; sl@0: #endif sl@0: sl@0: // low memory notification stuff sl@0: TBool iMemoryLow; // ETrue if kernel has notified us that memory has fallen below a specified threshold sl@0: TInt iLowMemoryThreshold; sl@0: sl@0: // index of the next cacheline in iUsedQueue to steal if sl@0: // all cachelines are in use sl@0: TInt iNextCacheLineToSteal; sl@0: sl@0: friend class CCacheManagerFactory; sl@0: friend class CCacheClient; sl@0: }; sl@0: sl@0: sl@0: NONSHARABLE_CLASS(TGlobalFileCacheSettings) sl@0: { sl@0: public: sl@0: static void ReadPropertiesFile(); sl@0: sl@0: static TBool Enabled(); sl@0: static TInt CacheSize(); sl@0: static TInt MaxLockedSize(); sl@0: static TInt LowMemoryThreshold(); sl@0: private: sl@0: static TBool iEnabled; sl@0: static TInt32 iCacheSize; sl@0: static TInt32 iMaxLockedSize; sl@0: static TInt32 iLowMemoryThreshold; sl@0: }; sl@0: sl@0: #endif // !defined(__SF_CACHE_MAN_H__)