Update contrib.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfile\sf_memory_client.cpp
24 #include <e32std_private.h>
29 #include "sf_memory_man.h"
30 #include "sf_memory_client.h"
33 CCacheMemoryClient::~CCacheMemoryClient()
35 const TUint32 segCnt = iTouchedRegionFlag <= iReservedRegionMarkInSegs ?
36 iReservedRegionMarkInSegs : iTouchedRegionFlag;
37 TInt r = DecommitSegments(iBase, segCnt);
38 if (r != KErrNone) // this 'if() {}' is to remove build warnings
42 iReusablePagePool.Close();
47 Static factory function for CCacheMemoryClient
48 @param aManager reference of CCacheMemoryManager that this client register with
49 @param aClientName the unique identification of CCacheMemoryClient
50 @param aOffsetInBytes the offset to the base position of CCacheMemoryManager it registered
51 @param aMinSizeInSegs the minimum client size in segments, equals to the number of reserved segments
52 @param aMaxSizeInSegs the maximum client size in segments
54 CCacheMemoryClient* CCacheMemoryClient::NewL(CCacheMemoryManager& aManager, const TDesC& aClientName, TUint32 aOffsetInBytes, TUint32 aMinSizeInSegs, TUint32 aMaxSizeInSegs)
56 // only create clients when sensible parameters are provided, otherwise will cause fatal error to file server
57 if (aMinSizeInSegs > 0 && aMaxSizeInSegs >= aMinSizeInSegs && aClientName.Length() > 0)
59 CCacheMemoryClient* self = new(ELeave) CCacheMemoryClient(aManager, aMinSizeInSegs, aMaxSizeInSegs);
60 CleanupStack::PushL(self);
61 self->ConstructL(aClientName, aOffsetInBytes);
62 CleanupStack::Pop(1, self);
69 Constructor of CCacheMemoryClient
70 @param aManager reference of CCacheMemoryManager that this client register with
71 @param aMinSizeInSegs the minimum client size in segments, equals to the number of reserved segments
72 @param aMaxSizeInSegs the maximum client size in segments
74 CCacheMemoryClient::CCacheMemoryClient(CCacheMemoryManager& aManager, TUint32 aMinSizeInSegs, TUint32 aMaxSizeInSegs)
76 iMinSizeInSegs(aMinSizeInSegs),
77 iMaxSizeInSegs(aMaxSizeInSegs)
82 Second phase constructor of CCacheMemoryClient
83 @param aClientName the unique identification of CCacheMemoryClient
84 @param aOffsetInBytes the offset to the base position of CCacheMemoryManager it registered
86 void CCacheMemoryClient::ConstructL(const TDesC& aClientName, TUint32 aOffsetInBytes)
88 __PRINT4(_L("CCacheMemoryClient::ConstructL(%S, min=%d, max=%d, base=0x%X)"), &aClientName, iMinSizeInSegs, iMaxSizeInSegs, iBase);
89 iName = HBufC::NewMaxL(aClientName.Length());
91 iSegSizeInBytesLog2 = iManager.SegmentSizeInBytesLog2();
92 iSegSizeInBytes = 1 << iSegSizeInBytesLog2;
93 iReusablePagePool.Close();
94 iReusablePagePool.ReserveL(iMinSizeInSegs);
95 iBase = iManager.Base() + aOffsetInBytes;
96 iReservedRegionMarkInSegs = iMinSizeInSegs;
97 TInt r = iManager.AllocateAndLockSegments(iBase, iReservedRegionMarkInSegs);
99 User::LeaveIfError(r);
100 iTouchedRegionFlag = 0;
101 __PRINT(_L("CCacheMemoryClient::ConstructL() return 0"));
105 Reset the client state, this is normally issued from the cache it connected with.
106 For exmaple, a FAT volume is dismounted so the directory cache needs to be reset.
107 Although the cache is reset, the CCacheMemoryClient object should not be destroyed and the reserved region should still
108 be hold to make sure when the cache re-connect with the CCacheMemoryClient, it will not fail due to OOM conditions.
113 EXPORT_C void CCacheMemoryClient::Reset()
115 __PRINT3(_L("CCacheMemoryClient::Reset(%S, reserved=%d, touched=%d)"), iName, iReservedRegionMarkInSegs, iTouchedRegionFlag);
117 // reset the cache memeory client to initial states:
118 // 1. all memory that have been 'touched' should be decommitted
119 // 2. the reserved region of memory should be re-locked
121 // if we have touched more than reserved region of memory, we shall decommit all of them
122 if (iTouchedRegionFlag > iReservedRegionMarkInSegs)
124 TInt r = DecommitSegments(iBase, iTouchedRegionFlag);
125 if (r != KErrNone) // this 'if() {}' is to remove build warnings in debug mode, same is below
130 else // otherwise we decommit the reserved region of memory only.
132 TInt r = DecommitSegments(iBase, iReservedRegionMarkInSegs);
133 if (r != KErrNone) // this 'if() {}' is to remove build warnings in debug mode, same is below
139 // re-lock the reserved region of memory
140 TInt r = iManager.AllocateAndLockSegments(iBase, iReservedRegionMarkInSegs);
146 iTouchedRegionFlag = 0;
147 iReusablePagePool.Close();
148 iReusablePagePool.Reserve(iReservedRegionMarkInSegs);
152 Commit an unused set of contiguous segments.
153 @param aSegmentCount the segment number to be commited.
154 @return TUint8* the starting ram address of the commited segments.
159 EXPORT_C TUint8* CCacheMemoryClient::AllocateAndLockSegments(TUint32 aSegmentCount)
161 __PRINT4(_L("CCacheMemoryClient::AllocateAndLockSegments(%S, segs=%d, reserved=%d, touched=%d)"), iName, aSegmentCount, iReservedRegionMarkInSegs, iTouchedRegionFlag);
162 // __PRINT2(_L("iBase = 0x%x, segcnt = %d"), iBase, aSegmentCount);
164 // if we are walking through the reserved region first time, we should
165 // make assumption that this area is locked already
166 if (iTouchedRegionFlag + aSegmentCount <= iReservedRegionMarkInSegs)
168 addr = iBase + (iTouchedRegionFlag << iSegSizeInBytesLog2);
169 iTouchedRegionFlag += aSegmentCount;
170 // __PRINT3(_L("!! USED RESERVED SEGS: addr=0x%x, touched=%d, reserved=%d"), addr, iTouchedRegionFlag, iReservedRegionMarkInSegs);
174 // if we have used up reserved region, get new pages from reusable pool first
175 if (iReusablePagePool.Count())
177 addr = iReusablePagePool[0];
178 iReusablePagePool.Remove(0);
179 // __PRINT2(_L("!! USED REUSABLE POOL SEGS: addr=0x%x, reusable.Count()=%d"), addr, iReusablePagePool.Count());
181 // or we grow the touched region flag
184 addr = iBase + (iTouchedRegionFlag << iSegSizeInBytesLog2);
185 iTouchedRegionFlag += aSegmentCount;
186 // __PRINT2(_L("!! GROW TOUCHED SEGS: addr=0x%x, touched=%d"), addr, iTouchedRegionFlag);
189 // parameter validation
190 ASSERT(((addr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount <= iMaxSizeInSegs);
191 if(((addr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount > iMaxSizeInSegs)
197 TInt r = iManager.AllocateAndLockSegments(addr, aSegmentCount);
205 Decommit a set of contiguous segments.
206 @param aStartRamAddr the start ram address of the region to be decommitted.
207 @param aSegmentCount the segment number to be decommited.
208 @return KErrNone if succeed, otherwise a system-wide error code.
213 EXPORT_C TInt CCacheMemoryClient::DecommitSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
215 __PRINT4(_L("CCacheMemoryClient::DecommitSegments(%S, reserved=%d, touched=%d, segNo=%d)"), iName, iReservedRegionMarkInSegs, iTouchedRegionFlag, aSegmentCount);
216 // parameter validation
217 if(aStartRamAddr < iBase ||
218 (((aStartRamAddr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount > iMaxSizeInSegs))
224 TInt err = iManager.DecommitSegments(aStartRamAddr, aSegmentCount);
225 ASSERT(err == KErrNone);
228 iReusablePagePool.Append(aStartRamAddr);
233 Lock a set of contiguous segments.
234 @param aStartRamAddr the start ram address of the region to be locked.
235 @param aSegmentCount the segment number to be locked.
236 @return KErrNone if succeed, otherwise a system-wide error code.
241 EXPORT_C TInt CCacheMemoryClient::LockSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
243 __PRINT4(_L("CCacheMemoryClient::LockSegments(%S, reserved=%d, touched=%d, segNo=%d)"), iName, iReservedRegionMarkInSegs, iTouchedRegionFlag, (aStartRamAddr - iBase) >> iSegSizeInBytesLog2);
244 // parameter validation
245 if(aStartRamAddr < iBase ||
246 (((aStartRamAddr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount > iMaxSizeInSegs))
251 return iManager.LockSegments(aStartRamAddr, aSegmentCount);
255 Unlock a set of contiguous segments.
256 @param aStartRamAddr the start ram address of the region to be unlocked.
257 @param aSegmentCount the segment number to be unlocked.
258 @return KErrNone if succeed, otherwise a system-wide error code.
263 EXPORT_C TInt CCacheMemoryClient::UnlockSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
265 __PRINT4(_L("CCacheMemoryClient::UnlockSegments(%S, reserved=%d, touched=%d, segNo=%d)"), iName, iReservedRegionMarkInSegs, iTouchedRegionFlag, (aStartRamAddr - iBase) >> iSegSizeInBytesLog2);
266 // validate parameters
267 if(aStartRamAddr < iBase ||
268 (((aStartRamAddr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount > iMaxSizeInSegs))
273 return iManager.UnlockSegments(aStartRamAddr, aSegmentCount);
276 //////////////////////////// auxiliary functions /////////////////////////
277 TUint32 CCacheMemoryClient::MaxSizeInBytes()
279 return iMaxSizeInSegs << iSegSizeInBytesLog2;
282 const TDesC& CCacheMemoryClient::Name() const