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