sl@0
|
1 |
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of the License "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// f32\sfile\sf_cache_man.h
|
sl@0
|
15 |
//
|
sl@0
|
16 |
//
|
sl@0
|
17 |
|
sl@0
|
18 |
/**
|
sl@0
|
19 |
@file
|
sl@0
|
20 |
@internalTechnology
|
sl@0
|
21 |
*/
|
sl@0
|
22 |
|
sl@0
|
23 |
#if !defined(__SF_CACHE_MAN_H__)
|
sl@0
|
24 |
#define __SF_CACHE_MAN_H__
|
sl@0
|
25 |
|
sl@0
|
26 |
#ifdef _DEBUG
|
sl@0
|
27 |
#define __SIMULATE_LOCK_FAILURES__
|
sl@0
|
28 |
#endif
|
sl@0
|
29 |
|
sl@0
|
30 |
// forward ref
|
sl@0
|
31 |
class CCacheManager;
|
sl@0
|
32 |
class CCacheClient;
|
sl@0
|
33 |
|
sl@0
|
34 |
const TInt KByteToByteShift = 10;
|
sl@0
|
35 |
|
sl@0
|
36 |
enum TCacheManagerFault
|
sl@0
|
37 |
{
|
sl@0
|
38 |
ENoCacheManager = 0,
|
sl@0
|
39 |
ECacheAlreadyCreated = 1,
|
sl@0
|
40 |
EIllegalDriveNumber = 2,
|
sl@0
|
41 |
EIllegalCacheSize = 3,
|
sl@0
|
42 |
EIllegalPageSize = 4,
|
sl@0
|
43 |
EInvalidAllocCount = 5,
|
sl@0
|
44 |
EInvalidLockCount = 6,
|
sl@0
|
45 |
EInvalidFillCount = 7,
|
sl@0
|
46 |
EAppendToFreeQueueFailed = 8,
|
sl@0
|
47 |
ESegmentNotFound = 9,
|
sl@0
|
48 |
EUnlockFailed = 10,
|
sl@0
|
49 |
EInvalidSegmentCount = 11,
|
sl@0
|
50 |
EInvalidAddress = 12,
|
sl@0
|
51 |
EInvalidDirtyCount = 13,
|
sl@0
|
52 |
EDecommitFailed = 14,
|
sl@0
|
53 |
EUnexpectedCommitFailure = 15,
|
sl@0
|
54 |
EUnexpectedLockFailure = 16,
|
sl@0
|
55 |
EInvalidCacheLine = 17,
|
sl@0
|
56 |
EInvalidClient = 18,
|
sl@0
|
57 |
ERemovingEmptyUnlocked = 19,
|
sl@0
|
58 |
EFreeingLockedCacheLine = 20,
|
sl@0
|
59 |
EFreeingDirtyCacheLine = 21,
|
sl@0
|
60 |
ESetDirtyNotLocked = 22,
|
sl@0
|
61 |
EClearDirtyNotLocked = 23,
|
sl@0
|
62 |
ESetFilledNotLocked = 24,
|
sl@0
|
63 |
EManagerNotLocked = 25,
|
sl@0
|
64 |
EExtendingUnownedCacheline = 26,
|
sl@0
|
65 |
EUnlockingUnownedCacheline = 27,
|
sl@0
|
66 |
EInvalidLockedPageStart = 28,
|
sl@0
|
67 |
EInvalidLockedPageCount = 29,
|
sl@0
|
68 |
EInvalidLockRange = 30,
|
sl@0
|
69 |
ESetDirtyInvalidLockRange = 31,
|
sl@0
|
70 |
ELockingAndAlreadyDirty = 32,
|
sl@0
|
71 |
EInvalidStats = 33
|
sl@0
|
72 |
};
|
sl@0
|
73 |
|
sl@0
|
74 |
|
sl@0
|
75 |
class CCacheManagerFactory
|
sl@0
|
76 |
{
|
sl@0
|
77 |
public:
|
sl@0
|
78 |
static void CreateL();
|
sl@0
|
79 |
static TInt Destroy();
|
sl@0
|
80 |
static CCacheManager* CacheManager();
|
sl@0
|
81 |
private:
|
sl@0
|
82 |
static CCacheManager* iCacheManager;
|
sl@0
|
83 |
};
|
sl@0
|
84 |
|
sl@0
|
85 |
|
sl@0
|
86 |
NONSHARABLE_CLASS(CCacheManager) : public CBase
|
sl@0
|
87 |
{
|
sl@0
|
88 |
private:
|
sl@0
|
89 |
|
sl@0
|
90 |
class TCacheLine
|
sl@0
|
91 |
{
|
sl@0
|
92 |
public:
|
sl@0
|
93 |
TUint8* iAddr;
|
sl@0
|
94 |
TUint8 iAllocatedSegments; // number of allocated pages
|
sl@0
|
95 |
TUint8 iFilledSegments; // number of full pages (i.e. pages with data in)
|
sl@0
|
96 |
TUint8 iDirtySegments; // number of dirty pages
|
sl@0
|
97 |
TUint8 iLockCount; // number of times cacheline has been locked
|
sl@0
|
98 |
TUint8 iLockedSegmentStart; // zero based index of first locked paged
|
sl@0
|
99 |
TUint8 iLockedSegmentCount; // number of locked pages
|
sl@0
|
100 |
TUint8 iSpare[2]; // padding
|
sl@0
|
101 |
CCacheClient* iClient; // owner of this cacheline
|
sl@0
|
102 |
TInt64 iPos; // arbitrary data owned by client
|
sl@0
|
103 |
};
|
sl@0
|
104 |
|
sl@0
|
105 |
public:
|
sl@0
|
106 |
CCacheClient* CreateClientL();
|
sl@0
|
107 |
void RegisterClient(CCacheClient& aClient);
|
sl@0
|
108 |
void DeregisterClient(CCacheClient& aClient);
|
sl@0
|
109 |
|
sl@0
|
110 |
|
sl@0
|
111 |
TInt SegmentSize();
|
sl@0
|
112 |
TInt SegmentSizeLog2();
|
sl@0
|
113 |
TInt64 SegmentSizeMask();
|
sl@0
|
114 |
TInt CacheLineSize();
|
sl@0
|
115 |
TInt CacheLineSizeLog2();
|
sl@0
|
116 |
TInt CacheLineSizeInSegments();
|
sl@0
|
117 |
|
sl@0
|
118 |
// called from CCacheClient
|
sl@0
|
119 |
TInt AllocateAndLockCacheLine(CCacheClient* aClient, TInt64 aPos, const TCacheLine*& aCacheLine, TInt aSegmentCount);
|
sl@0
|
120 |
TInt ReAllocateAndLockCacheLine(CCacheClient* aClient, TInt64 aPos, const TCacheLine& aCacheLine, TInt aSegmentCount);
|
sl@0
|
121 |
|
sl@0
|
122 |
TInt ExtendCacheLine(CCacheClient* aClient, const TCacheLine& aCacheLine, TInt aSegmentCount);
|
sl@0
|
123 |
void RemoveEmptySegments(CCacheClient* aClient, const TCacheLine& aCacheLine);
|
sl@0
|
124 |
|
sl@0
|
125 |
TInt LockCacheLine(CCacheClient* aClient, const TCacheLine& aCacheLine, TInt aLockedPageStart, TInt aLockedPageCount);
|
sl@0
|
126 |
TBool UnlockCacheLine(CCacheClient* aClient, const TCacheLine& aCacheLine);
|
sl@0
|
127 |
|
sl@0
|
128 |
TBool FreeCacheLine(CCacheClient* aClient, const TCacheLine& aCacheLine);
|
sl@0
|
129 |
|
sl@0
|
130 |
|
sl@0
|
131 |
TInt LockCount(CCacheClient* aClient, const TCacheLine& aCacheLine);
|
sl@0
|
132 |
TInt FillCount(CCacheClient* aClient, const TCacheLine& aCacheLine);
|
sl@0
|
133 |
TInt DirtyCount(CCacheClient* aClient, const TCacheLine& aCacheLine);
|
sl@0
|
134 |
TBool TooManyLockedSegments();
|
sl@0
|
135 |
|
sl@0
|
136 |
void SetFilled(CCacheClient* aClient, const TCacheLine& aCacheLine, TInt aSegmentCount);
|
sl@0
|
137 |
void SetDirty(CCacheClient* aClient, const TCacheLine& aCacheLine, TInt aSegmentCount);
|
sl@0
|
138 |
void ClearDirty(CCacheClient* aClient, const TCacheLine& aCacheLine);
|
sl@0
|
139 |
TBool InUse(const TCacheLine& aCacheLine);
|
sl@0
|
140 |
|
sl@0
|
141 |
// called from CKernEventNotifier::FreeMemoryChangeCallback()
|
sl@0
|
142 |
void FreeMemoryChanged(TBool aMemoryLow);
|
sl@0
|
143 |
|
sl@0
|
144 |
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
|
sl@0
|
145 |
void DumpCache();
|
sl@0
|
146 |
void DumpCacheLine(TCacheLine& aCacheLine);
|
sl@0
|
147 |
void SimulateLockFailureMode(TBool aEnable);
|
sl@0
|
148 |
void AllocateMaxSegments(TBool aEnable);
|
sl@0
|
149 |
TBool AllocateMaxSegments();
|
sl@0
|
150 |
// stats
|
sl@0
|
151 |
TFileCacheStats& Stats();
|
sl@0
|
152 |
|
sl@0
|
153 |
void SimulateWriteFailure();
|
sl@0
|
154 |
TBool SimulateWriteFailureEnabled();
|
sl@0
|
155 |
TBool SimulatedFailure(TInt& aFailureCount);
|
sl@0
|
156 |
#endif
|
sl@0
|
157 |
|
sl@0
|
158 |
private:
|
sl@0
|
159 |
~CCacheManager();
|
sl@0
|
160 |
|
sl@0
|
161 |
CCacheManager(TUint aCacheSize);
|
sl@0
|
162 |
void ConstructL();
|
sl@0
|
163 |
|
sl@0
|
164 |
inline TUint8* Base();
|
sl@0
|
165 |
|
sl@0
|
166 |
inline void CacheLock();
|
sl@0
|
167 |
inline void CacheUnlock();
|
sl@0
|
168 |
|
sl@0
|
169 |
TBool StealCacheLine(CCacheClient* aClient);
|
sl@0
|
170 |
|
sl@0
|
171 |
TInt Lock(TUint8* aAddr, TInt aSegmentCount);
|
sl@0
|
172 |
TInt Unlock(TUint8* aAddr, TInt aSegmentCount);
|
sl@0
|
173 |
TInt Commit(TUint8* aAddr, TInt aSegmentCount);
|
sl@0
|
174 |
TInt Decommit(TUint8* aAddr, TInt aSegmentCount);
|
sl@0
|
175 |
|
sl@0
|
176 |
static CCacheManager* NewCacheL(TInt aUncommitedCacheSize);
|
sl@0
|
177 |
|
sl@0
|
178 |
void FreeCacheLine(TCacheLine& aCacheLine);
|
sl@0
|
179 |
|
sl@0
|
180 |
private:
|
sl@0
|
181 |
|
sl@0
|
182 |
RFastLock iLock;
|
sl@0
|
183 |
|
sl@0
|
184 |
TCacheLine* iCacheLines;
|
sl@0
|
185 |
RPointerArray<TCacheLine> iFreeQueue;
|
sl@0
|
186 |
RPointerArray<TCacheLine> iUsedQueue;
|
sl@0
|
187 |
|
sl@0
|
188 |
TUint8* iBase;
|
sl@0
|
189 |
|
sl@0
|
190 |
TInt iNumOfCacheLines;
|
sl@0
|
191 |
|
sl@0
|
192 |
TInt iCacheLineSize;
|
sl@0
|
193 |
TInt iCacheLineSizeLog2;
|
sl@0
|
194 |
|
sl@0
|
195 |
TInt iCacheSize;
|
sl@0
|
196 |
TInt iMaxLockedSegments;
|
sl@0
|
197 |
|
sl@0
|
198 |
TInt iSegmentsPerCacheLine;
|
sl@0
|
199 |
|
sl@0
|
200 |
TInt iLockedSegmentCount;
|
sl@0
|
201 |
|
sl@0
|
202 |
RChunk iChunk;
|
sl@0
|
203 |
TBool iSimulateLockFailureMode;
|
sl@0
|
204 |
|
sl@0
|
205 |
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
|
sl@0
|
206 |
TBool iManagerLocked;
|
sl@0
|
207 |
TInt iLockFailureCount;
|
sl@0
|
208 |
TInt iCommitFailureCount;
|
sl@0
|
209 |
TInt iAllocFailureCount;
|
sl@0
|
210 |
TBool iAllocateMaxSegments;
|
sl@0
|
211 |
|
sl@0
|
212 |
TFileCacheStats iStats;
|
sl@0
|
213 |
TBool iSimulateWriteFailure;
|
sl@0
|
214 |
#endif
|
sl@0
|
215 |
|
sl@0
|
216 |
// low memory notification stuff
|
sl@0
|
217 |
TBool iMemoryLow; // ETrue if kernel has notified us that memory has fallen below a specified threshold
|
sl@0
|
218 |
TInt iLowMemoryThreshold;
|
sl@0
|
219 |
|
sl@0
|
220 |
// index of the next cacheline in iUsedQueue to steal if
|
sl@0
|
221 |
// all cachelines are in use
|
sl@0
|
222 |
TInt iNextCacheLineToSteal;
|
sl@0
|
223 |
|
sl@0
|
224 |
friend class CCacheManagerFactory;
|
sl@0
|
225 |
friend class CCacheClient;
|
sl@0
|
226 |
};
|
sl@0
|
227 |
|
sl@0
|
228 |
|
sl@0
|
229 |
NONSHARABLE_CLASS(TGlobalFileCacheSettings)
|
sl@0
|
230 |
{
|
sl@0
|
231 |
public:
|
sl@0
|
232 |
static void ReadPropertiesFile();
|
sl@0
|
233 |
|
sl@0
|
234 |
static TBool Enabled();
|
sl@0
|
235 |
static TInt CacheSize();
|
sl@0
|
236 |
static TInt MaxLockedSize();
|
sl@0
|
237 |
static TInt LowMemoryThreshold();
|
sl@0
|
238 |
private:
|
sl@0
|
239 |
static TBool iEnabled;
|
sl@0
|
240 |
static TInt32 iCacheSize;
|
sl@0
|
241 |
static TInt32 iMaxLockedSize;
|
sl@0
|
242 |
static TInt32 iLowMemoryThreshold;
|
sl@0
|
243 |
};
|
sl@0
|
244 |
|
sl@0
|
245 |
#endif // !defined(__SF_CACHE_MAN_H__)
|