os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_memory_client.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2008-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_memory_client.cpp
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
#include <e32std.h>
sl@0
    24
#include <e32std_private.h>
sl@0
    25
#include "sf_std.h"
sl@0
    26
#include <e32uid.h>
sl@0
    27
#include <e32wins.h>
sl@0
    28
#include <f32file.h>
sl@0
    29
#include "sf_memory_man.h"
sl@0
    30
#include "sf_memory_client.h"
sl@0
    31
sl@0
    32
sl@0
    33
CCacheMemoryClient::~CCacheMemoryClient()
sl@0
    34
	{
sl@0
    35
	const TUint32 segCnt = iTouchedRegionFlag <= iReservedRegionMarkInSegs ? 
sl@0
    36
										iReservedRegionMarkInSegs : iTouchedRegionFlag;
sl@0
    37
	TInt r = DecommitSegments(iBase, segCnt);
sl@0
    38
	if (r != KErrNone)  // this 'if() {}' is to remove build warnings
sl@0
    39
	{
sl@0
    40
	ASSERT(0);
sl@0
    41
	}
sl@0
    42
	iReusablePagePool.Close();
sl@0
    43
	delete iName;
sl@0
    44
	}
sl@0
    45
sl@0
    46
/**
sl@0
    47
Static factory function for CCacheMemoryClient
sl@0
    48
@param	aManager	reference of CCacheMemoryManager that this client register with
sl@0
    49
@param	aClientName	the unique identification of CCacheMemoryClient
sl@0
    50
@param	aOffsetInBytes	the offset to the base position of CCacheMemoryManager it registered
sl@0
    51
@param	aMinSizeInSegs	the minimum client size in segments, equals to the number of reserved segments
sl@0
    52
@param	aMaxSizeInSegs	the maximum client size in segments
sl@0
    53
*/
sl@0
    54
CCacheMemoryClient* CCacheMemoryClient::NewL(CCacheMemoryManager& aManager, const TDesC& aClientName, TUint32 aOffsetInBytes, TUint32 aMinSizeInSegs, TUint32 aMaxSizeInSegs)
sl@0
    55
	{
sl@0
    56
	// only create clients when sensible parameters are provided, otherwise will cause fatal error to file server 
sl@0
    57
	if (aMinSizeInSegs > 0 && aMaxSizeInSegs >= aMinSizeInSegs && aClientName.Length() > 0)
sl@0
    58
		{
sl@0
    59
		CCacheMemoryClient* self = new(ELeave) CCacheMemoryClient(aManager, aMinSizeInSegs, aMaxSizeInSegs);
sl@0
    60
		CleanupStack::PushL(self);
sl@0
    61
		self->ConstructL(aClientName, aOffsetInBytes);
sl@0
    62
		CleanupStack::Pop(1, self);
sl@0
    63
		return self;
sl@0
    64
		}
sl@0
    65
	return NULL;
sl@0
    66
	}
sl@0
    67
sl@0
    68
/**
sl@0
    69
Constructor of CCacheMemoryClient
sl@0
    70
@param	aManager	reference of CCacheMemoryManager that this client register with
sl@0
    71
@param	aMinSizeInSegs	the minimum client size in segments, equals to the number of reserved segments
sl@0
    72
@param	aMaxSizeInSegs	the maximum client size in segments
sl@0
    73
*/
sl@0
    74
CCacheMemoryClient::CCacheMemoryClient(CCacheMemoryManager& aManager, TUint32 aMinSizeInSegs, TUint32 aMaxSizeInSegs)
sl@0
    75
:iManager(aManager),
sl@0
    76
iMinSizeInSegs(aMinSizeInSegs),
sl@0
    77
iMaxSizeInSegs(aMaxSizeInSegs)
sl@0
    78
	{
sl@0
    79
	}
sl@0
    80
sl@0
    81
/**
sl@0
    82
Second phase constructor of CCacheMemoryClient
sl@0
    83
@param	aClientName	the unique identification of CCacheMemoryClient
sl@0
    84
@param	aOffsetInBytes	the offset to the base position of CCacheMemoryManager it registered
sl@0
    85
*/
sl@0
    86
void CCacheMemoryClient::ConstructL(const TDesC& aClientName, TUint32 aOffsetInBytes)
sl@0
    87
	{
sl@0
    88
    __PRINT4(_L("CCacheMemoryClient::ConstructL(%S, min=%d, max=%d, base=0x%X)"), &aClientName, iMinSizeInSegs, iMaxSizeInSegs, iBase);
sl@0
    89
	iName = HBufC::NewMaxL(aClientName.Length());
sl@0
    90
	*iName = aClientName;
sl@0
    91
	iSegSizeInBytesLog2 = iManager.SegmentSizeInBytesLog2();
sl@0
    92
	iSegSizeInBytes = 1 << iSegSizeInBytesLog2;
sl@0
    93
	iReusablePagePool.Close();
sl@0
    94
	iReusablePagePool.ReserveL(iMinSizeInSegs);
sl@0
    95
	iBase = iManager.Base() + aOffsetInBytes;
sl@0
    96
	iReservedRegionMarkInSegs = iMinSizeInSegs;
sl@0
    97
	TInt r = iManager.AllocateAndLockSegments(iBase, iReservedRegionMarkInSegs);
sl@0
    98
	ASSERT(r==KErrNone);
sl@0
    99
	User::LeaveIfError(r);
sl@0
   100
	iTouchedRegionFlag = 0;
sl@0
   101
	__PRINT(_L("CCacheMemoryClient::ConstructL() return 0"));
sl@0
   102
	}
sl@0
   103
sl@0
   104
/**
sl@0
   105
Reset the client state, this is normally issued from the cache it connected with.
sl@0
   106
For exmaple, a FAT volume is dismounted so the directory cache needs to be reset.
sl@0
   107
Although the cache is reset, the CCacheMemoryClient object should not be destroyed and the reserved region should still 
sl@0
   108
be hold to make sure when the cache re-connect with the CCacheMemoryClient, it will not fail due to OOM conditions.
sl@0
   109
sl@0
   110
@internalTechnology
sl@0
   111
@released
sl@0
   112
*/
sl@0
   113
EXPORT_C void CCacheMemoryClient::Reset()
sl@0
   114
	{
sl@0
   115
	__PRINT3(_L("CCacheMemoryClient::Reset(%S, reserved=%d, touched=%d)"), iName, iReservedRegionMarkInSegs, iTouchedRegionFlag);
sl@0
   116
	
sl@0
   117
	// reset the cache memeory client to initial states: 
sl@0
   118
	//     1. all memory that have been 'touched' should be decommitted
sl@0
   119
	//     2. the reserved region of memory should be re-locked
sl@0
   120
sl@0
   121
	// if we have touched more than reserved region of memory, we shall decommit all of them 
sl@0
   122
	if (iTouchedRegionFlag > iReservedRegionMarkInSegs)
sl@0
   123
	    {
sl@0
   124
	    TInt r = DecommitSegments(iBase, iTouchedRegionFlag);
sl@0
   125
	    if (r != KErrNone)  // this 'if() {}' is to remove build warnings in debug mode, same is below
sl@0
   126
	        {
sl@0
   127
	        ASSERT(0);
sl@0
   128
	        }
sl@0
   129
	    }
sl@0
   130
	else   // otherwise we decommit the reserved region of memory only.
sl@0
   131
	    {
sl@0
   132
	    TInt r = DecommitSegments(iBase, iReservedRegionMarkInSegs);
sl@0
   133
	    if (r != KErrNone)  // this 'if() {}' is to remove build warnings in debug mode, same is below
sl@0
   134
	        {
sl@0
   135
	        ASSERT(0);
sl@0
   136
	        }
sl@0
   137
	    }
sl@0
   138
sl@0
   139
    // re-lock the reserved region of memory
sl@0
   140
	TInt r = iManager.AllocateAndLockSegments(iBase, iReservedRegionMarkInSegs);
sl@0
   141
    if (r != KErrNone)
sl@0
   142
        {
sl@0
   143
        ASSERT(0);
sl@0
   144
        }
sl@0
   145
sl@0
   146
	iTouchedRegionFlag = 0;
sl@0
   147
	iReusablePagePool.Close();
sl@0
   148
	iReusablePagePool.Reserve(iReservedRegionMarkInSegs);
sl@0
   149
	}
sl@0
   150
sl@0
   151
/**
sl@0
   152
Commit an unused set of contiguous segments. 
sl@0
   153
@param	aSegmentCount	the segment number to be commited.
sl@0
   154
@return	TUint8*	the starting ram address of the commited segments.
sl@0
   155
sl@0
   156
@internalTechnology
sl@0
   157
@released
sl@0
   158
*/
sl@0
   159
EXPORT_C TUint8* CCacheMemoryClient::AllocateAndLockSegments(TUint32 aSegmentCount)
sl@0
   160
	{
sl@0
   161
	__PRINT4(_L("CCacheMemoryClient::AllocateAndLockSegments(%S, segs=%d, reserved=%d, touched=%d)"), iName, aSegmentCount, iReservedRegionMarkInSegs, iTouchedRegionFlag);
sl@0
   162
//	__PRINT2(_L("iBase = 0x%x, segcnt = %d"), iBase, aSegmentCount);
sl@0
   163
    TUint8* addr = NULL;
sl@0
   164
    // if we are walking through the reserved region first time, we should
sl@0
   165
    // make assumption that this area is locked already
sl@0
   166
    if (iTouchedRegionFlag + aSegmentCount <= iReservedRegionMarkInSegs)
sl@0
   167
       	{
sl@0
   168
       	addr = iBase + (iTouchedRegionFlag << iSegSizeInBytesLog2);
sl@0
   169
       	iTouchedRegionFlag += aSegmentCount;
sl@0
   170
//       	__PRINT3(_L("!! USED RESERVED SEGS: addr=0x%x, touched=%d, reserved=%d"), addr, iTouchedRegionFlag, iReservedRegionMarkInSegs);
sl@0
   171
       	return addr;
sl@0
   172
       	}
sl@0
   173
    
sl@0
   174
	// if we have used up reserved region, get new pages from reusable pool first
sl@0
   175
    if (iReusablePagePool.Count())
sl@0
   176
    	{
sl@0
   177
		addr = iReusablePagePool[0];
sl@0
   178
		iReusablePagePool.Remove(0);
sl@0
   179
//       	__PRINT2(_L("!! USED REUSABLE POOL SEGS: addr=0x%x, reusable.Count()=%d"), addr, iReusablePagePool.Count());
sl@0
   180
    	}
sl@0
   181
    // or we grow the touched region flag
sl@0
   182
    else
sl@0
   183
    	{
sl@0
   184
    	addr = iBase + (iTouchedRegionFlag << iSegSizeInBytesLog2);
sl@0
   185
    	iTouchedRegionFlag += aSegmentCount;
sl@0
   186
//       	__PRINT2(_L("!! GROW TOUCHED SEGS: addr=0x%x, touched=%d"), addr, iTouchedRegionFlag);
sl@0
   187
    	}
sl@0
   188
	
sl@0
   189
    // parameter validation
sl@0
   190
    ASSERT(((addr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount <= iMaxSizeInSegs);
sl@0
   191
    if(((addr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount > iMaxSizeInSegs)
sl@0
   192
    	{
sl@0
   193
    	ASSERT(0);
sl@0
   194
    	return NULL;
sl@0
   195
    	}
sl@0
   196
sl@0
   197
    TInt r = iManager.AllocateAndLockSegments(addr, aSegmentCount);
sl@0
   198
	if (r != KErrNone)
sl@0
   199
		return NULL;
sl@0
   200
sl@0
   201
	return addr;
sl@0
   202
	}
sl@0
   203
sl@0
   204
/**
sl@0
   205
Decommit a set of contiguous segments. 
sl@0
   206
@param	aStartRamAddr	the start ram address of the region to be decommitted.
sl@0
   207
@param	aSegmentCount	the segment number to be decommited.
sl@0
   208
@return		KErrNone if succeed, otherwise a system-wide error code.
sl@0
   209
sl@0
   210
@internalTechnology
sl@0
   211
@released
sl@0
   212
*/
sl@0
   213
EXPORT_C TInt CCacheMemoryClient::DecommitSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
sl@0
   214
	{
sl@0
   215
	__PRINT4(_L("CCacheMemoryClient::DecommitSegments(%S, reserved=%d, touched=%d, segNo=%d)"), iName, iReservedRegionMarkInSegs, iTouchedRegionFlag, aSegmentCount);
sl@0
   216
	// parameter validation
sl@0
   217
	if(aStartRamAddr < iBase || 
sl@0
   218
			(((aStartRamAddr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount > iMaxSizeInSegs))
sl@0
   219
		{
sl@0
   220
		ASSERT(0);
sl@0
   221
		return KErrArgument;
sl@0
   222
		}
sl@0
   223
	
sl@0
   224
	TInt err = iManager.DecommitSegments(aStartRamAddr, aSegmentCount);
sl@0
   225
	ASSERT(err == KErrNone);
sl@0
   226
	if (err != KErrNone)
sl@0
   227
		return err;
sl@0
   228
	iReusablePagePool.Append(aStartRamAddr);
sl@0
   229
	return KErrNone;
sl@0
   230
	}
sl@0
   231
sl@0
   232
/**
sl@0
   233
Lock a set of contiguous segments. 
sl@0
   234
@param	aStartRamAddr	the start ram address of the region to be locked.
sl@0
   235
@param	aSegmentCount	the segment number to be locked.
sl@0
   236
@return		KErrNone if succeed, otherwise a system-wide error code.
sl@0
   237
sl@0
   238
@internalTechnology
sl@0
   239
@released
sl@0
   240
*/
sl@0
   241
EXPORT_C TInt CCacheMemoryClient::LockSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
sl@0
   242
	{
sl@0
   243
	__PRINT4(_L("CCacheMemoryClient::LockSegments(%S, reserved=%d, touched=%d, segNo=%d)"), iName, iReservedRegionMarkInSegs, iTouchedRegionFlag, (aStartRamAddr - iBase) >> iSegSizeInBytesLog2);
sl@0
   244
	// parameter validation
sl@0
   245
	if(aStartRamAddr < iBase || 
sl@0
   246
			(((aStartRamAddr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount > iMaxSizeInSegs))
sl@0
   247
		{
sl@0
   248
		ASSERT(0);
sl@0
   249
		return KErrArgument;
sl@0
   250
		}
sl@0
   251
	return iManager.LockSegments(aStartRamAddr, aSegmentCount);
sl@0
   252
	}
sl@0
   253
sl@0
   254
/**
sl@0
   255
Unlock a set of contiguous segments. 
sl@0
   256
@param	aStartRamAddr	the start ram address of the region to be unlocked.
sl@0
   257
@param	aSegmentCount	the segment number to be unlocked.
sl@0
   258
@return		KErrNone if succeed, otherwise a system-wide error code.
sl@0
   259
sl@0
   260
@internalTechnology
sl@0
   261
@released
sl@0
   262
*/
sl@0
   263
EXPORT_C TInt CCacheMemoryClient::UnlockSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
sl@0
   264
	{
sl@0
   265
	__PRINT4(_L("CCacheMemoryClient::UnlockSegments(%S, reserved=%d, touched=%d, segNo=%d)"), iName, iReservedRegionMarkInSegs, iTouchedRegionFlag, (aStartRamAddr - iBase) >> iSegSizeInBytesLog2);
sl@0
   266
	// validate parameters
sl@0
   267
	if(aStartRamAddr < iBase || 
sl@0
   268
			(((aStartRamAddr - iBase) >> iSegSizeInBytesLog2) + aSegmentCount > iMaxSizeInSegs))
sl@0
   269
		{
sl@0
   270
		ASSERT(0);
sl@0
   271
		return KErrArgument;
sl@0
   272
		}
sl@0
   273
	return iManager.UnlockSegments(aStartRamAddr, aSegmentCount);
sl@0
   274
	}
sl@0
   275
sl@0
   276
//////////////////////////// auxiliary functions /////////////////////////
sl@0
   277
TUint32 CCacheMemoryClient::MaxSizeInBytes()
sl@0
   278
	{
sl@0
   279
	return iMaxSizeInSegs  << iSegSizeInBytesLog2;
sl@0
   280
	}
sl@0
   281
sl@0
   282
const TDesC& CCacheMemoryClient::Name() const
sl@0
   283
	{
sl@0
   284
	return *iName;
sl@0
   285
	}
sl@0
   286