1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/server/t_rcache.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1813 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32test\server\t_rcache.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +/**
1.22 + @file
1.23 + @internalTechnology
1.24 +*/
1.25 +#define __E32TEST_EXTENSION__
1.26 +#include <f32file.h>
1.27 +#include <e32test.h>
1.28 +#include <e32svr.h>
1.29 +#include <e32const.h>
1.30 +#include <e32const_private.h>
1.31 +#include <f32dbg.h>
1.32 +#include "t_server.h"
1.33 +#include <e32twin.h>
1.34 +#include <e32rom.h>
1.35 +#include <hal.h>
1.36 +#include <u32hal.h>
1.37 +
1.38 +const TInt KTotalCacheSize = 32 * 1024 * 1024;
1.39 +const TInt KDefaultCacheSize = (128 + 12) * 1024;
1.40 +const TInt KFilesNeededToFillCache = (KTotalCacheSize / KDefaultCacheSize) + 2;
1.41 +
1.42 +
1.43 +//----------------------------------------------------------------------------------------------
1.44 +//! @SYMTestCaseID PBASE-T_RCACHE-0190
1.45 +//! @SYMTestType CIT
1.46 +//! @SYMPREQ PREQ914
1.47 +//! @SYMTestCaseDesc This test case is exercising the Read Caching functionality added to
1.48 +//! the File Server. There are negative and positive tests.
1.49 +//! @SYMTestActions 0 setup the environment to execute the tests
1.50 +//! 1 TestNegative creates situations where the cached content needs to be
1.51 +//! flushed or removed from the cache by corrupting files and verifies
1.52 +//! the cache behaviour
1.53 +//! 2 TestSimpleRead ensures that the cache is working in the simple cases,
1.54 +//! with a combination of sync and async reads:
1.55 +//! a. The file fits in the cache
1.56 +//! b. The file doesn't fit in the cache
1.57 +//! 3 TestRepeatedRead verifies the cache behaviour when a file is read an
1.58 +//! arbitrary number of times, with and without other operations ongoing
1.59 +//! 4 TestReadAhead reads 3 times from a file and verifies that the read
1.60 +//! ahead functionality acts afterwards.
1.61 +//! 5 TestConcurrent reads files concurrently and verifies how the cache
1.62 +//! copes with it.
1.63 +//! 6 TestFillCache fills the cache and then executes TestSimpleRead.
1.64 +//!
1.65 +//! @SYMTestExpectedResults finishes if the read cache behaves as expected, panics otherwise
1.66 +//! @SYMTestPriority High
1.67 +//! @SYMTestStatus Implemented
1.68 +//----------------------------------------------------------------------------------------------
1.69 +
1.70 +
1.71 +////////////////////////////////////////////////////////////
1.72 +// Template functions encapsulating ControlIo magic
1.73 +//
1.74 +GLDEF_D template <class C>
1.75 +GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
1.76 +{
1.77 + TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
1.78 +
1.79 + TInt r = fs.ControlIo(drv, fkn, ptrC);
1.80 +
1.81 + return r;
1.82 +}
1.83 +
1.84 +GLDEF_D RTest test(_L("T_RCACHE"));
1.85 +
1.86 +GLDEF_D RFs TheFs;
1.87 +GLDEF_D TInt gDrive;
1.88 +GLDEF_D TFileName gSessionPath;
1.89 +GLDEF_D TChar gDriveToTest;
1.90 +TThreadId gMainThreadId;
1.91 +
1.92 +LOCAL_D HBufC8* gBuf = NULL;
1.93 +LOCAL_D TPtr8 gBufReadPtr(NULL, 0);
1.94 +LOCAL_D HBufC8* gBufSec = NULL;
1.95 +LOCAL_D TPtr8 gBufWritePtr(NULL, 0);
1.96 +
1.97 +LOCAL_D const TInt KOneK = 1024;
1.98 +LOCAL_D const TInt KOneMeg = KOneK * 1024;
1.99 +LOCAL_D const TInt KBlockSize = KOneK;
1.100 +LOCAL_D const TInt KWaitRequestsTableSize = 256;
1.101 +
1.102 +LOCAL_D TInt gSecondFileSize = 0;
1.103 +LOCAL_D TInt gFirstFileSize = 0;
1.104 +LOCAL_D TInt gCurrentFileSize = 0;
1.105 +
1.106 +LOCAL_D TInt64 gMediaSize = 0;
1.107 +
1.108 +LOCAL_D TTimeIntervalMicroSeconds gTimeTakenBigFile(0);
1.109 +LOCAL_D TBuf16<25> gFirstFile;
1.110 +LOCAL_D TBuf16<25> gSecondFile;
1.111 +LOCAL_D TBuf16<25> gCurrentFile;
1.112 +
1.113 +LOCAL_D TInt gNextFile = 0;
1.114 +LOCAL_D TTime gTime1;
1.115 +LOCAL_D TTime gTime2;
1.116 +_LIT(KMsg1, "1st read timing: %d\n");
1.117 +_LIT(KMsg2, "2nd read timing: %d\n");
1.118 +_LIT(KMsg3, "3rd read timing: %d\n");
1.119 +
1.120 +LOCAL_D RSemaphore gSync;
1.121 +
1.122 +// Concurrent Threads
1.123 +LOCAL_D RThread gThread1;
1.124 +LOCAL_D RThread gThread2;
1.125 +LOCAL_D RSemaphore client;
1.126 +LOCAL_D const TInt KHeapSize = 0x4000;
1.127 +LOCAL_D const TInt KMaxHeapSize = 0x100000;
1.128 +LOCAL_D TBool gPagedRom = EFalse;
1.129 +
1.130 +enum TTestState
1.131 + {
1.132 + EThreadWait,
1.133 + EThreadSignal,
1.134 + ENoThreads
1.135 + };
1.136 +
1.137 +/** Formats the drive
1.138 +
1.139 + @param aDrive Drive to be formatted
1.140 + @param aFormatMode Mode for the format operation
1.141 +*/
1.142 +LOCAL_C void Formatting(TInt aDrive, TUint aFormatMode )
1.143 + {
1.144 +
1.145 + test.Next(_L("Format"));
1.146 + TBuf<4> driveBuf = _L("?:\\");
1.147 + driveBuf[0]=(TText)(aDrive+'A');
1.148 + RFormat format;
1.149 + TInt count;
1.150 + TInt r = format.Open(TheFs,driveBuf,aFormatMode,count);
1.151 + test_KErrNone(r);
1.152 + while(count)
1.153 + {
1.154 + TInt r = format.Next(count);
1.155 + test_KErrNone(r);
1.156 + }
1.157 + format.Close();
1.158 + }
1.159 +
1.160 +/** Verifies the content of a buffer (all the letters are like the first one)
1.161 +
1.162 + @param aBuffer Buffer to be verified
1.163 +
1.164 + @return KErrNone if all the letters are the same, KErrCorrupt otherwise
1.165 +*/
1.166 +LOCAL_C TInt VerifyBuffer(TDes8& aBuffer)
1.167 + {
1.168 + TChar c = aBuffer[0];
1.169 +
1.170 + for(TInt i = 1; i < aBuffer.Length(); i++)
1.171 + {
1.172 + if(i%32 != 0)
1.173 + {
1.174 + if(c != (TChar)(aBuffer[i] - 1))
1.175 + return KErrCorrupt;
1.176 + }
1.177 + else
1.178 + {
1.179 + if(aBuffer[i] != aBuffer[0])
1.180 + return KErrCorrupt;
1.181 + }
1.182 + c = aBuffer[i];
1.183 + }
1.184 +
1.185 + return KErrNone;
1.186 + }
1.187 +
1.188 +/** Fills a buffer with character aC, aC+1, aC+2, ..., aC+20, aC, etc
1.189 +
1.190 + @param aBuffer Buffer to be filled, output
1.191 + @param aLength Length to be filled
1.192 + @param aC Character to be used to fill the buffer
1.193 +*/
1.194 +LOCAL_C void FillBuffer(TDes8& aBuffer, TInt aLength, TChar aC)
1.195 + {
1.196 + test (aBuffer.MaxLength() >= aLength);
1.197 + for(TInt i = 0; i < aLength; i++)
1.198 + {
1.199 + aBuffer.Append((i%32) + aC);
1.200 + }
1.201 + }
1.202 +
1.203 +/** Returns true if fat filesystem present on aDrive
1.204 +
1.205 + @param aFsSession Session on the File Server
1.206 + @param aDrive Drive to be looked at
1.207 +*/
1.208 +LOCAL_C TBool IsFSFAT(RFs &aFsSession,TInt aDrive)
1.209 + {
1.210 + TFileName f;
1.211 + TInt r = aFsSession.FileSystemName(f,aDrive);
1.212 +
1.213 + if (r != KErrNone)
1.214 + {
1.215 + test.Printf(_L("Unable to get file system name\n"));
1.216 + return EFalse;
1.217 + }
1.218 +
1.219 + return (f.CompareF(_L("Fat")) == 0);
1.220 + }
1.221 +
1.222 +/** Generates a file name of the form FFFFF*<aPos>.TXT (aLong.3)
1.223 +
1.224 + @param aBuffer The filename will be returned here
1.225 + @param aLong Defines the longitude of the file name
1.226 + @param aPos Defines the number that will be attached to the filename
1.227 +*/
1.228 +GLDEF_C void FileNameGen(TDes16& aBuffer, TInt aLong, TInt aPos)
1.229 +{
1.230 + TInt padding;
1.231 + TInt i = 0;
1.232 + TBuf16<10> tempbuf;
1.233 +
1.234 + _LIT(KNumber,"%d");
1.235 + tempbuf.Format(KNumber,aPos);
1.236 + padding = aLong-tempbuf.Size()/2;
1.237 + aBuffer = _L("");
1.238 + while(i < padding)
1.239 + {
1.240 + aBuffer.Append('F');
1.241 + i++;
1.242 + }
1.243 + aBuffer.Append(tempbuf);
1.244 +
1.245 + _LIT(KExtension1, ".TXT");
1.246 + aBuffer.Append(KExtension1);
1.247 +}
1.248 +
1.249 +/** Delete content of directory
1.250 +
1.251 + @param aDir Target directory
1.252 +
1.253 + @return Error returned if any, otherwise KErrNone
1.254 +*/
1.255 +LOCAL_C TInt DeleteAll(TDes16& aDir)
1.256 +{
1.257 + TBuf16<100> dir;
1.258 + CFileMan* fMan = CFileMan::NewL(TheFs);
1.259 + TInt r=0;
1.260 +
1.261 + dir = aDir;
1.262 + dir.Append(_L("F*.*"));
1.263 + r = fMan->Delete(dir);
1.264 +
1.265 + delete fMan;
1.266 + return r;
1.267 +}
1.268 +
1.269 +/** Waits for all the TRequestStatus in status[] to complete
1.270 +
1.271 + @param status Array of TRequestStatus
1.272 + @param aLength Length to be filled
1.273 + @param aC Character to be used to fill the buffer
1.274 +*/
1.275 +LOCAL_C void WaitForAll(TRequestStatus* status, TInt aSize)
1.276 +{
1.277 + TInt i = 0;
1.278 +
1.279 + RTest test(_L("T_RCACHE"));
1.280 +
1.281 + while(i < aSize)
1.282 + {
1.283 + User::WaitForRequest(status[i]);
1.284 + test(status[i] == KErrNone);
1.285 + i++;
1.286 + }
1.287 +
1.288 + test.Close();
1.289 +}
1.290 +
1.291 +/** Reads the parameters from the comand line
1.292 + and updates the appropriate variables
1.293 +*/
1.294 +LOCAL_C void parseCommandLine()
1.295 +{
1.296 + TBuf<0x100> cmd;
1.297 + User::CommandLine(cmd);
1.298 + TLex lex(cmd);
1.299 + TPtrC token = lex.NextToken();
1.300 + TInt r=0;
1.301 +
1.302 + if(token.Length() != 0)
1.303 + {
1.304 + gDriveToTest = token[0];
1.305 + gDriveToTest.UpperCase();
1.306 + }
1.307 + else
1.308 + {
1.309 + gDriveToTest = 'C';
1.310 + }
1.311 +
1.312 + r = TheFs.CharToDrive(gDriveToTest,gDrive);
1.313 + test_KErrNone(r);
1.314 + gSessionPath = _L("?:\\F32-TST\\");
1.315 + gSessionPath[0] = (TUint16) gDriveToTest;
1.316 + test.Printf(_L("\nCLP=%C\n"),(TInt)gDriveToTest);
1.317 +}
1.318 +
1.319 +/** Writes a file synchronously in blocks of aBlockSize size
1.320 +
1.321 + @param fs RFs object
1.322 + @param aFile File name
1.323 + @param aSize Size of the file in bytes
1.324 + @param aBlockSize Size of the blocks to be used in bytes
1.325 + @param aState Determines if the operation is being done in the main process
1.326 + or in a thread
1.327 + @param aReadBack Reads the file back if ETrue. This is used for Read-ahead testing to ensure
1.328 + what is written is also read back through the media driver's cache. If the
1.329 + file is bigger than the cache, then subsequent streaming reads starting from
1.330 + position zero will have to be re-read from the media.
1.331 +
1.332 + @return Returns KErrNone if everything ok, otherwise it panics
1.333 +*/
1.334 +LOCAL_C TInt WriteFile(RFs& fs, TDes16& aFile, TInt aSize, TInt aBlockSize, TDes8& aBuf, TTestState aState, TBool aReadBack = EFalse)
1.335 +{
1.336 + RTest test(_L("T_RCACHE"));
1.337 +
1.338 + TInt r = 0;
1.339 + RFile fileWrite;
1.340 + TInt pos = 0;
1.341 +
1.342 + test(aBlockSize>0);
1.343 + test((aSize%aBlockSize) == 0); // Ensure the size of the file is a multiple of the block size
1.344 +
1.345 + if(aState == EThreadWait)
1.346 + {
1.347 + gSync.Wait();
1.348 + }
1.349 +
1.350 + // delete file first to ensure it's contents are not in the cache (file may be be on the closed file queue)
1.351 + r = fs.Delete(aFile);
1.352 + test_Value(r, r == KErrNone || r == KErrNotFound);
1.353 +
1.354 + r = fileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
1.355 + test_KErrNone(r);
1.356 +
1.357 + TInt j = 0;
1.358 + while(j < aSize)
1.359 + {
1.360 + r = fileWrite.Write(pos, aBuf);
1.361 + test_KErrNone(r);
1.362 +
1.363 + if (aReadBack)
1.364 + {
1.365 + r = fileWrite.Read(pos, aBuf);
1.366 + test_KErrNone(r);
1.367 + }
1.368 +
1.369 + if((j>(aSize/2))&&(aState == EThreadSignal))
1.370 + {
1.371 + gSync.Signal();
1.372 + aState = ENoThreads;
1.373 + }
1.374 + j += aBlockSize;
1.375 + pos += aBlockSize;
1.376 + }
1.377 + fileWrite.Close();
1.378 + test.Close();
1.379 +
1.380 + return KErrNone;
1.381 +}
1.382 +
1.383 +/** Read File in blocks of size aBlockSize
1.384 +
1.385 + @param fs RFs object
1.386 + @param aFile File name
1.387 + @param aBlockSize Size of the blocks to be used in bytes
1.388 +
1.389 + @return Returns KErrNone if everything ok, otherwise it panics
1.390 +*/
1.391 +LOCAL_C TInt ReadFile(RFs& fs, TDes16& aFile, TInt aBlockSize)
1.392 +{
1.393 + RTest test(_L("T_RCACHE"));
1.394 +
1.395 + TInt r = 0, size = 0;
1.396 + RFile fileRead;
1.397 +
1.398 + test(aBlockSize>0); // Block size must be greater than 0
1.399 +
1.400 + r = fileRead.Open(fs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
1.401 + test_KErrNone(r);
1.402 +
1.403 + r = fileRead.Size(size);
1.404 + test_KErrNone(r);
1.405 +
1.406 + TInt j = 0;
1.407 + while(j < size)
1.408 + {
1.409 + r = fileRead.Read(gBufReadPtr, aBlockSize);
1.410 + test_KErrNone(r);
1.411 + j += aBlockSize;
1.412 + }
1.413 + fileRead.Close();
1.414 + test.Close();
1.415 +
1.416 + return KErrNone;
1.417 +}
1.418 +
1.419 +/** Write a file asynchronously in blocks of aBlockSize size
1.420 +
1.421 + @param fs RFs object
1.422 + @param aFileWrite RFile object, needs to exist beyond the scope of this function
1.423 + @param aFile File name
1.424 + @param aSize Size of the file in bytes
1.425 + @param aBlockSize Size of the blocks to be used in bytes
1.426 + @param aStatus TRequestStatus array for all the requests
1.427 +*/
1.428 +LOCAL_C void WriteFileAsync(RFs& fs, RFile& aFileWrite, TDes16& aFile, TInt aSize, TInt aBlockSize, TRequestStatus aStatus[])
1.429 +{
1.430 + RTest test(_L("T_RCACHE"));
1.431 +
1.432 + TInt r = 0;
1.433 +
1.434 + test(aBlockSize>0);
1.435 + test((aSize%aBlockSize) == 0); // Ensure the size of the file is a multiple of the block size
1.436 +
1.437 +
1.438 + // delete file first to ensure it's contents are not in the cache (file may be be on the closed file queue)
1.439 + r = fs.Delete(aFile);
1.440 + test(r == KErrNone || r == KErrNotFound);
1.441 +
1.442 + r = aFileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
1.443 + test_KErrNone(r);
1.444 +
1.445 + TInt j = 0, i = 0;
1.446 + while(j < aSize)
1.447 + {
1.448 + aFileWrite.Write(gBufWritePtr,aStatus[i]);
1.449 + r = aStatus[i].Int();
1.450 + if (r != KErrNone && r != KRequestPending)
1.451 + {
1.452 + test.Printf(_L("Write %d returned %d\n"), i, r);
1.453 + test(0);
1.454 + }
1.455 + i++;
1.456 +
1.457 + j += aBlockSize;
1.458 + }
1.459 + test.Close();
1.460 +}
1.461 +
1.462 +/** Read a file asynchronously in blocks of aBlockSize size
1.463 +
1.464 + @param fs RFs object
1.465 + @param aFileRead RFile object, needs to exist beyond the scope of this function
1.466 + @param aFile File name
1.467 + @param aSize Size of the file in bytes
1.468 + @param aBlockSize Size of the blocks to be used in bytes
1.469 + @param aStatus TRequestStatus array for all the requests
1.470 +
1.471 + @return KErrNone
1.472 +*/
1.473 +LOCAL_C TInt ReadFileAsync(RFs& fs,RFile& aFileRead, TDes16& aFile, TInt aBlockSize,TRequestStatus aStatus[], TInt aFileSize)
1.474 + {
1.475 + RTest test(_L("T_RCACHE"));
1.476 +
1.477 + TInt r = 0;
1.478 + TInt size = 0;
1.479 +
1.480 + test(aBlockSize > 0);
1.481 +
1.482 + r = aFileRead.Open(fs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
1.483 + test_KErrNone(r);
1.484 +
1.485 + r = aFileRead.Size(size);
1.486 + test_KErrNone(r);
1.487 +
1.488 + test(size == aFileSize);
1.489 +
1.490 + TInt j = 0, i = 0;
1.491 + while(j < size)
1.492 + {
1.493 + aFileRead.Read(gBufReadPtr,aStatus[i]);
1.494 + r = aStatus[i].Int();
1.495 + if (r != KErrNone && r != KRequestPending)
1.496 + {
1.497 + test.Printf(_L("Read %d returned %d\n"), i, r);
1.498 + test(0);
1.499 + }
1.500 + i++;
1.501 +
1.502 + j += aBlockSize;
1.503 + }
1.504 +
1.505 + test.Close();
1.506 + return KErrNone;
1.507 + }
1.508 +
1.509 +/** Measure the time taken for this file to be written synchronously
1.510 +*/
1.511 +LOCAL_C TInt WriteTestFile(TDes16& aFile, TInt aSize, TBool aReadBack = EFalse)
1.512 +{
1.513 + RTest test(_L("T_RCACHE"));
1.514 +
1.515 + TTime startTime;
1.516 + TTime endTime;
1.517 + TInt r = 0;
1.518 +
1.519 + startTime.HomeTime();
1.520 +
1.521 + r = WriteFile(TheFs,aFile, aSize, KBlockSize, gBufWritePtr, ENoThreads, aReadBack);
1.522 + test_KErrNone(r);
1.523 +
1.524 + endTime.HomeTime();
1.525 +
1.526 + gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
1.527 +
1.528 + test.Close();
1.529 + return I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.530 +}
1.531 +
1.532 +/** Measure the time taken for this file to be read synchronously
1.533 +*/
1.534 +LOCAL_C TInt ReadTestFile(TDes16& aFile)
1.535 +{
1.536 + TTime startTime;
1.537 + TTime endTime;
1.538 +
1.539 + startTime.HomeTime();
1.540 + ReadFile(TheFs,aFile, KBlockSize);
1.541 + endTime.HomeTime();
1.542 +
1.543 + gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
1.544 +
1.545 + return I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.546 +}
1.547 +
1.548 +/** Read asynchronously the test file from the disc
1.549 +
1.550 +*/
1.551 +LOCAL_C TInt ReadAsyncTestFile(TDes16& aFile, TInt aSize)
1.552 +{
1.553 + RTest test(_L("T_RCACHE"));
1.554 +
1.555 + TTime startTime;
1.556 + TTime endTime;
1.557 + TRequestStatus status[KWaitRequestsTableSize];
1.558 + RFs fs;
1.559 + RFile file;
1.560 +
1.561 + TInt r = fs.Connect();
1.562 + test (r == KErrNone);
1.563 +
1.564 + startTime.HomeTime();
1.565 +
1.566 + ReadFileAsync(fs, file, aFile, KBlockSize, status, aSize);
1.567 + WaitForAll(status, aSize/KBlockSize);
1.568 +
1.569 + endTime.HomeTime();
1.570 +
1.571 + gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
1.572 +
1.573 + file.Close();
1.574 + fs.Close();
1.575 + test.Close();
1.576 + return I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.577 +}
1.578 +
1.579 +/** Write a file for the simple case
1.580 +
1.581 +*/
1.582 +LOCAL_C TInt WriteFileT(TAny* )
1.583 +{
1.584 + RTest test(_L("T_RCACHE"));
1.585 + RFs fs;
1.586 + TInt r = fs.Connect();
1.587 + test_KErrNone(r);
1.588 +
1.589 + r = fs.SetSessionPath(gSessionPath);
1.590 + test_KErrNone(r);
1.591 + gTime1.HomeTime();
1.592 +
1.593 + r = WriteFile(fs,gCurrentFile,gCurrentFileSize, KBlockSize,gBufWritePtr, ENoThreads);
1.594 + test_KErrNone(r);
1.595 +
1.596 + gTime2.HomeTime();
1.597 +
1.598 + fs.Close();
1.599 + test.Close();
1.600 +
1.601 + gTimeTakenBigFile = I64LOW(gTime2.MicroSecondsFrom(gTime1).Int64());
1.602 +
1.603 + client.Signal();
1.604 +
1.605 + return ETrue;
1.606 +}
1.607 +
1.608 +/** Write a file for the concurrent case
1.609 +
1.610 +*/
1.611 +LOCAL_C TInt WriteFileT2(TAny* )
1.612 +{
1.613 + RTest test(_L("T_RCACHE"));
1.614 + RFs fs;
1.615 + TInt r = fs.Connect();
1.616 + test_KErrNone(r);
1.617 + RFile file;
1.618 + TRequestStatus status[KWaitRequestsTableSize];
1.619 +
1.620 +
1.621 + r = fs.SetSessionPath(gSessionPath);
1.622 + test_KErrNone(r);
1.623 +
1.624 + WriteFileAsync(fs,file,gFirstFile,gSecondFileSize, KBlockSize, status);
1.625 + WaitForAll(status,gSecondFileSize/KBlockSize);
1.626 +
1.627 + TInt size = 0;
1.628 + file.Size(size);
1.629 + test( size == gSecondFileSize );
1.630 +
1.631 + file.Close();
1.632 + fs.Close();
1.633 +
1.634 + test.Close();
1.635 +
1.636 + client.Signal();
1.637 +
1.638 + return ETrue;
1.639 +}
1.640 +
1.641 +/** Write a file for the simple case
1.642 +
1.643 +*/
1.644 +LOCAL_C TInt ReadFileT(TAny* )
1.645 +{
1.646 + RTest test(_L("T_RCACHE"));
1.647 + RFs fs;
1.648 + TInt r = fs.Connect();
1.649 + test_KErrNone(r);
1.650 +
1.651 + r = fs.SetSessionPath(gSessionPath);
1.652 + test_KErrNone(r);
1.653 + gTime1.HomeTime();
1.654 +
1.655 + ReadFile(fs,gCurrentFile, KBlockSize);
1.656 +
1.657 + gTime2.HomeTime();
1.658 +
1.659 + fs.Close();
1.660 + test.Close();
1.661 +
1.662 + gTimeTakenBigFile = I64LOW(gTime2.MicroSecondsFrom(gTime1).Int64());
1.663 +
1.664 + client.Signal();
1.665 +
1.666 + return ETrue;
1.667 +}
1.668 +
1.669 +/** Simple case, cache effect shown
1.670 +
1.671 +*/
1.672 +LOCAL_C void TestSimpleRead()
1.673 +{
1.674 + TInt r = 0;
1.675 + TInt time = 0;
1.676 + TInt time2 = 0;
1.677 + TInt time3 = 0;
1.678 + TInt tcreate = 0;
1.679 +
1.680 + test.Start(_L(""));
1.681 +
1.682 + test.Next(_L("File fits in: read sync + read sync + read async\n"));
1.683 +
1.684 + tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
1.685 + test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
1.686 +
1.687 + time = ReadTestFile(gSecondFile);
1.688 + test.Printf(KMsg1,time);
1.689 + time2 = ReadTestFile(gSecondFile);
1.690 + test.Printf(KMsg2,time2);
1.691 + time3 = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
1.692 + test.Printf(KMsg3,time3);
1.693 +#if !defined(__WINS__)
1.694 + if (gPagedRom)
1.695 + test.Printf(_L("Skipping timing test on paged ROM\n"));
1.696 + else
1.697 + test((time2 <= time) && (time3 < time));
1.698 +#endif
1.699 +
1.700 + r = DeleteAll(gSessionPath);
1.701 + test(r == KErrNone || r == KErrInUse);
1.702 +
1.703 + // Simple case filling/reading the cache from different threads
1.704 + test.Next(_L("File fits in: read sync (another thread) + read sync + read async\n"));
1.705 + gCurrentFile = gSecondFile;
1.706 + gCurrentFileSize = gSecondFileSize;
1.707 +
1.708 + TBuf<20> buf = _L("Write File");
1.709 + r = gThread1.Create(buf,WriteFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
1.710 + test_KErrNone(r);
1.711 +
1.712 + gThread1.Resume();
1.713 + client.Wait();
1.714 +
1.715 + tcreate = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.716 +
1.717 + test.Printf(_L("Time to create the file from a thread: %d ms\n"),tcreate);
1.718 +
1.719 + buf = _L("Read File");
1.720 + r = gThread2.Create(buf,ReadFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
1.721 + test(r == KErrNone);
1.722 +
1.723 + gThread2.Resume();
1.724 + client.Wait();
1.725 +
1.726 + gThread1.Close();
1.727 + gThread2.Close();
1.728 +
1.729 + time = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.730 + test.Printf(KMsg1,time);
1.731 + time2 = ReadTestFile(gSecondFile);
1.732 + test.Printf(KMsg2,time2);
1.733 + time3 = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
1.734 + test.Printf(KMsg3,time3);
1.735 +#if !defined(__WINS__)
1.736 + if (gPagedRom)
1.737 + test.Printf(_L("Skipping timing test on paged ROM\n"));
1.738 + else
1.739 + test((time2<=time) && (time3<time));
1.740 +#endif
1.741 +
1.742 + r = DeleteAll(gSessionPath);
1.743 + test(r == KErrNone || r == KErrInUse);
1.744 +
1.745 +
1.746 + test.Next(_L("File doesn't fit in: read sync + read sync + read async\n"));
1.747 +
1.748 + tcreate = WriteTestFile(gFirstFile,gFirstFileSize);
1.749 + test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
1.750 +
1.751 + time = ReadTestFile(gFirstFile);
1.752 + test.Printf(KMsg1,time);
1.753 + time2 = ReadTestFile(gFirstFile);
1.754 + test.Printf(KMsg2,time2);
1.755 + time3 = ReadAsyncTestFile(gFirstFile,gFirstFileSize);
1.756 + test.Printf(KMsg3,time3);
1.757 +
1.758 + #if !defined(__WINS__)
1.759 + // this isn't valid as the file doesn't fit in the cache, so there's no reason why
1.760 + // the second read should be any faster than the first
1.761 + // test((time2 <= time) && (time3 < time));
1.762 + #endif
1.763 +
1.764 +
1.765 + r = DeleteAll(gSessionPath);
1.766 + test(r == KErrNone || r == KErrInUse);
1.767 +
1.768 +
1.769 + test.Next(_L("File doesn't fit in: read sync (another thread) + read sync + read async\n"));
1.770 + gCurrentFile = gFirstFile;
1.771 + gCurrentFileSize = gFirstFileSize;
1.772 +
1.773 + buf = _L("Write Big File");
1.774 + r = gThread1.Create(buf,WriteFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
1.775 + test_KErrNone(r);
1.776 +
1.777 + gThread1.Resume();
1.778 + client.Wait();
1.779 +
1.780 + tcreate = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.781 +
1.782 + test.Printf(_L("Time to create the file from a thread: %d ms\n"),tcreate);
1.783 +
1.784 + buf = _L("Read Big File");
1.785 + r = gThread2.Create(buf,ReadFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
1.786 + test(r == KErrNone);
1.787 +
1.788 + gThread2.Resume();
1.789 + client.Wait();
1.790 +
1.791 + gThread1.Close();
1.792 + gThread2.Close();
1.793 +
1.794 + time = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.795 + test.Printf(KMsg1,time);
1.796 + time2 = ReadTestFile(gFirstFile);
1.797 + test.Printf(KMsg2,time2);
1.798 + time3 = ReadAsyncTestFile(gFirstFile,gFirstFileSize);
1.799 + test.Printf(KMsg3,time3);
1.800 +
1.801 + #if !defined(__WINS__)
1.802 + // this isn't valid as the file doesn't fit in the cache, so there's no reason why
1.803 + // the second read should be any faster than the first
1.804 + // test((time2 <= time) && (time3 < time));
1.805 + #endif
1.806 +
1.807 + r = DeleteAll(gSessionPath);
1.808 + test(r == KErrNone || r == KErrInUse);
1.809 +
1.810 + test.End();
1.811 +}
1.812 +
1.813 +/** Thread to create file and read from it
1.814 +
1.815 +*/
1.816 +LOCAL_C TInt ReadAnotherEntry(TAny* )
1.817 +{
1.818 + RTest test(_L("T_RCACHE"));
1.819 + RFs fs;
1.820 + TInt r = fs.Connect();
1.821 + RFile file;
1.822 + HBufC8* lBufSec = NULL;
1.823 + TPtr8 lBufReadPtr(NULL, 0);
1.824 +
1.825 + TRAPD(res2,lBufSec = HBufC8::NewL(KBlockSize+1));
1.826 + test(res2 == KErrNone && lBufSec != NULL);
1.827 + lBufReadPtr.Set(lBufSec->Des());
1.828 +
1.829 + test(r == KErrNone);
1.830 + r = fs.SetSessionPath(gSessionPath);
1.831 +
1.832 +
1.833 + // delete file first to ensure it's contents are not in the cache (file may be be on the closed file queue)
1.834 + r = fs.Delete(gFirstFile);
1.835 + test(r == KErrNone || r == KErrNotFound);
1.836 +
1.837 + r = file.Create(fs,gFirstFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
1.838 +
1.839 + if(r == KErrAlreadyExists)
1.840 + {
1.841 + r = file.Open(fs,gFirstFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
1.842 + test_KErrNone(r);
1.843 + }
1.844 +
1.845 + r = file.Write(gBufWritePtr);
1.846 + test_KErrNone(r);
1.847 +
1.848 + client.Signal();
1.849 +
1.850 + FOREVER
1.851 + {
1.852 + r = file.Read(gBufReadPtr, KBlockSize);
1.853 + test_KErrNone(r);
1.854 + }
1.855 +
1.856 +}
1.857 +
1.858 +/** Test the cache behaviour in repeated call situations
1.859 +
1.860 +*/
1.861 +LOCAL_C void TestRepeatedRead()
1.862 +{
1.863 + TInt r = 0;
1.864 + TInt time = 0;
1.865 + TInt i = 0;
1.866 + TInt tcreate = 0;
1.867 +
1.868 +
1.869 + test.Start(_L(""));
1.870 + test.Next(_L("File fits in: read sync / read async \n"));
1.871 +
1.872 + tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
1.873 + test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
1.874 + while(i < 20)
1.875 + {
1.876 + if(!(i % 2))
1.877 + {
1.878 + time = ReadTestFile(gSecondFile);
1.879 + test.Printf(_L("%d) Sync Read: %d\n"), i+1 , time);
1.880 + }
1.881 + else
1.882 + {
1.883 + time = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
1.884 + test.Printf(_L("%d) Async Read: %d\n"), i+1 , time);
1.885 + }
1.886 + i++;
1.887 + }
1.888 +
1.889 + r = DeleteAll(gSessionPath);
1.890 + test_KErrNone(r);
1.891 +
1.892 + test.Next(_L("File fits in: read sync / read async, with another thread using the drive \n"));
1.893 +
1.894 + TBuf<20> buf = _L("Noise Thread");
1.895 + r = gThread1.Create(buf,ReadAnotherEntry,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
1.896 + test_KErrNone(r);
1.897 +
1.898 + tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
1.899 + test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
1.900 +
1.901 + gThread1.Resume();
1.902 + client.Wait();
1.903 +
1.904 + i = 0;
1.905 + while(i < 20)
1.906 + {
1.907 + if(!(i%2))
1.908 + {
1.909 + time = ReadTestFile(gSecondFile);
1.910 + test.Printf(_L("%d) Sync Read: %d\n"), i+1 , time);
1.911 + }
1.912 + else
1.913 + {
1.914 + time = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
1.915 + test.Printf(_L("%d) Async Read: %d\n"), i+1 , time);
1.916 + }
1.917 + i++;
1.918 + }
1.919 +
1.920 + gThread1.Kill(KErrNone);
1.921 + gThread1.Close();
1.922 +
1.923 + r = DeleteAll(gSessionPath);
1.924 + test_KErrNone(r);
1.925 +
1.926 + test.End();
1.927 +}
1.928 +
1.929 +/** Concurrent operations testing
1.930 +
1.931 +*/
1.932 +LOCAL_C void TestConcurrent()
1.933 +{
1.934 + TInt r = 0;
1.935 + TInt time = 0;
1.936 + TInt time2 = 0;
1.937 + TInt time3 = 0;
1.938 +
1.939 + test.Start(_L("Write two files concurrently\n"));
1.940 +
1.941 + gCurrentFile = gSecondFile;
1.942 + gCurrentFileSize = gSecondFileSize;
1.943 +
1.944 + TBuf<20> buf = _L("Write Two Files 1");
1.945 + r = gThread1.Create(buf,WriteFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
1.946 + test_KErrNone(r);
1.947 +
1.948 + TBuf<20> buf2 = _L("Write Two Files 2");
1.949 + r = gThread2.Create(buf2,WriteFileT2,KDefaultStackSize*2,KHeapSize,KMaxHeapSize,NULL);
1.950 + test(r == KErrNone);
1.951 +
1.952 + gThread1.Resume();
1.953 + gThread2.Resume();
1.954 + client.Wait();
1.955 + client.Wait();
1.956 +
1.957 + test.Next(_L("Read the two files repeatedly\n"));
1.958 +
1.959 + test.Printf(_L("File 1:\n"));
1.960 + time = ReadTestFile(gSecondFile);
1.961 + test.Printf(KMsg1,time);
1.962 + time2 = ReadTestFile(gSecondFile);
1.963 + test.Printf(KMsg2,time2);
1.964 + time3 = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
1.965 + test.Printf(KMsg3,time3);
1.966 +
1.967 + test.Printf(_L("File 2:\n"));
1.968 +
1.969 + time = ReadTestFile(gFirstFile);
1.970 + test.Printf(KMsg1,time);
1.971 + time2 = ReadTestFile(gFirstFile);
1.972 + test.Printf(KMsg2,time2);
1.973 + time3 = ReadAsyncTestFile(gFirstFile,gSecondFileSize);
1.974 + test.Printf(KMsg3,time3);
1.975 +
1.976 + test.End();
1.977 +
1.978 + r = DeleteAll(gSessionPath);
1.979 + test_KErrNone(r);
1.980 +}
1.981 +
1.982 +/** Create file from other thread, to be cached
1.983 +
1.984 +*/
1.985 +LOCAL_C TInt CreateFile(TAny* )
1.986 +{
1.987 + RTest test(_L("T_RCACHE"));
1.988 + RFs fs;
1.989 + TInt r = fs.Connect();
1.990 + test(r == KErrNone);
1.991 +
1.992 + r = fs.SetSessionPath(gSessionPath);
1.993 + test(r == KErrNone);
1.994 +
1.995 + r = WriteFile(fs, gSecondFile, gSecondFileSize, KBlockSize, gBufWritePtr, EThreadSignal);
1.996 + test_KErrNone(r);
1.997 +
1.998 + return KErrNone;
1.999 +}
1.1000 +
1.1001 +LOCAL_C TBool FindPattern(TUint8 *aBuf, TUint8 *aPattern, TInt aLong, TInt *aOffSet)
1.1002 +{
1.1003 + TInt i = 0;
1.1004 + TBool found = EFalse;
1.1005 +
1.1006 + while((i < (aLong-4)) && !found)
1.1007 + {
1.1008 + found = (
1.1009 + (aBuf[i] == aPattern[0])&&
1.1010 + (aBuf[i+1] == aPattern[1])&&
1.1011 + (aBuf[i+2] == aPattern[2])&&
1.1012 + (aBuf[i+3] == aPattern[3])
1.1013 + );
1.1014 + i++;
1.1015 + }
1.1016 +
1.1017 + if(found)
1.1018 + *aOffSet = --i;
1.1019 +
1.1020 + return found;
1.1021 +}
1.1022 +
1.1023 +/** Corrupts the second file with Raw access
1.1024 +
1.1025 +*/
1.1026 +LOCAL_C void CorruptSecondFileRaw()
1.1027 +{
1.1028 + RRawDisk rDisk;
1.1029 + TUint8 gBuffer[4] =
1.1030 + {
1.1031 + 65,66,67,68
1.1032 + };
1.1033 + TUint8 gBufferB[4] =
1.1034 + {
1.1035 + 33,33,33,33
1.1036 + };
1.1037 + TPtr8 gBufferBPtr(&gBufferB[0], 4, 4);
1.1038 +
1.1039 + TUint8 gBuffer2[KBlockSize];
1.1040 + TPtr8 gBuffer2Ptr(&gBuffer2[0], KBlockSize);
1.1041 +
1.1042 + TInt r = rDisk.Open(TheFs,gDrive);
1.1043 + test_KErrNone(r);
1.1044 +
1.1045 + TInt64 pos = 0;
1.1046 + TBool found = EFalse;
1.1047 + TInt offset = 0;
1.1048 +
1.1049 + while(!found)
1.1050 + {
1.1051 + rDisk.Read(pos, gBuffer2Ptr);
1.1052 + found = FindPattern(gBuffer2, gBuffer, KBlockSize, &offset);
1.1053 + pos += (KBlockSize);
1.1054 + }
1.1055 + pos -= (KBlockSize+1);
1.1056 + pos = pos+offset;
1.1057 +
1.1058 + r = rDisk.Write(pos+4, gBufferBPtr);
1.1059 + test_KErrNone(r);
1.1060 +
1.1061 + rDisk.Close();
1.1062 +}
1.1063 +
1.1064 +/** Modifies the second file
1.1065 +
1.1066 +*/
1.1067 +LOCAL_C TInt CorruptSecondFile()
1.1068 +{
1.1069 + TInt r = 0;
1.1070 + RFile fileWrite;
1.1071 + HBufC8* dummy = NULL;
1.1072 + TPtr8 dummyPtr(NULL, 0);
1.1073 +
1.1074 + TRAPD(res,dummy = HBufC8::NewL(4));
1.1075 + test(res == KErrNone && dummy != NULL);
1.1076 +
1.1077 + dummyPtr.Set(dummy->Des());
1.1078 + FillBuffer(dummyPtr, 4, '1');
1.1079 +
1.1080 + r = fileWrite.Open(TheFs,gSecondFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
1.1081 + if(r != 0)
1.1082 + return r;
1.1083 + TInt pos = 30;
1.1084 + r = fileWrite.Seek(ESeekStart,pos);
1.1085 +
1.1086 + r = fileWrite.Write(dummyPtr);
1.1087 + if(r != 0)
1.1088 + return r;
1.1089 +
1.1090 + fileWrite.Close();
1.1091 +
1.1092 + delete dummy;
1.1093 +
1.1094 + return KErrNone;
1.1095 +}
1.1096 +
1.1097 +//
1.1098 +// Read the file verifying content
1.1099 +//
1.1100 +LOCAL_C TInt ReadTestFileVerif(TDes16& aFile, TBool aRaw)
1.1101 +{
1.1102 + TTime startTime;
1.1103 + TTime endTime;
1.1104 + TInt r = 0, size = 0;
1.1105 + RFile fileRead;
1.1106 + TInt corrupt = 0;
1.1107 + TBool isFat=IsFSFAT(TheFs,gDrive);
1.1108 +
1.1109 + startTime.HomeTime();
1.1110 +
1.1111 + r = fileRead.Open(TheFs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
1.1112 + test_KErrNone(r);
1.1113 +
1.1114 + r = fileRead.Size(size);
1.1115 + test_KErrNone(r);
1.1116 +
1.1117 + TInt j = 0;
1.1118 + while(j < size)
1.1119 + {
1.1120 + r = fileRead.Read(gBufReadPtr, KBlockSize);
1.1121 + if(aRaw)
1.1122 + {
1.1123 + if(isFat)
1.1124 + {
1.1125 + test_KErrNone(r);
1.1126 + }
1.1127 + else
1.1128 + {
1.1129 + if(r == KErrCorrupt)
1.1130 + corrupt++;
1.1131 + }
1.1132 + }
1.1133 + else
1.1134 + {
1.1135 + test_KErrNone(r);
1.1136 + }
1.1137 + j += KBlockSize;
1.1138 + r = VerifyBuffer(gBufReadPtr);
1.1139 + if(r == KErrCorrupt)
1.1140 + corrupt++;
1.1141 + }
1.1142 +
1.1143 + fileRead.Close();
1.1144 +
1.1145 + test(corrupt>0); // Ensure the cache returns the changed content
1.1146 +
1.1147 + endTime.HomeTime();
1.1148 +
1.1149 + gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
1.1150 +
1.1151 + return I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.1152 +}
1.1153 +
1.1154 +
1.1155 +/** Negative testing
1.1156 +
1.1157 +*/
1.1158 +LOCAL_C void TestNegative()
1.1159 +{
1.1160 + TInt r = 0;
1.1161 + TInt time, time2, time3;
1.1162 + TInt tcreate = 0;
1.1163 +
1.1164 + test.Start(_L(""));
1.1165 + // Kill a thread while writing, then read content
1.1166 + TBuf<20> buf = _L("A thread to kill");
1.1167 + gCurrentFile = gSecondFile;
1.1168 + gCurrentFileSize = gSecondFileSize;
1.1169 +
1.1170 + r = gThread1.Create(buf,CreateFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
1.1171 + test_KErrNone(r);
1.1172 +
1.1173 + gThread1.Resume();
1.1174 + gSync.Wait();
1.1175 + gThread1.Kill(KErrGeneral);
1.1176 + gThread1.Close();
1.1177 + test.Next(_L("Read after killing the write in the middle\n"));
1.1178 + time = ReadTestFile(gSecondFile);
1.1179 + test.Printf(KMsg1,time);
1.1180 + time2 = ReadTestFile(gSecondFile);
1.1181 + test.Printf(KMsg2,time2);
1.1182 +
1.1183 + // Read async the content
1.1184 + TInt size = 0;
1.1185 + TRequestStatus status[KWaitRequestsTableSize];
1.1186 + TTime startTime;
1.1187 + TTime endTime;
1.1188 + RFile fileRead;
1.1189 +
1.1190 + startTime.HomeTime();
1.1191 +
1.1192 + r = fileRead.Open(TheFs,gSecondFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
1.1193 + test_KErrNone(r);
1.1194 +
1.1195 + r = fileRead.Size(size);
1.1196 + test_KErrNone(r);
1.1197 +
1.1198 + TInt j = 0, i = 0;
1.1199 + while(j < size)
1.1200 + {
1.1201 + fileRead.Read(gBufReadPtr,status[i++]);
1.1202 + test_KErrNone(r);
1.1203 + j += KBlockSize;
1.1204 + }
1.1205 +
1.1206 + j = i;
1.1207 + i = 0;
1.1208 + while(i < j)
1.1209 + {
1.1210 + User::WaitForRequest(status[i++]);
1.1211 + }
1.1212 + fileRead.Close();
1.1213 + endTime.HomeTime();
1.1214 + gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
1.1215 + time3 = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
1.1216 +
1.1217 + test.Printf(KMsg3,time3);
1.1218 +
1.1219 + // Modify file in some position
1.1220 + test.Next(_L("Overwrite partially a file\n"));
1.1221 + Formatting(gDrive, EFullFormat);
1.1222 + r = TheFs.MkDirAll(gSessionPath);
1.1223 + if (r != KErrNone && r != KErrAlreadyExists)
1.1224 + {
1.1225 + test_KErrNone(r);
1.1226 + }
1.1227 +
1.1228 + tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
1.1229 + test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
1.1230 +
1.1231 + time = ReadTestFile(gSecondFile);
1.1232 + test.Printf(KMsg1,time);
1.1233 +
1.1234 + time = ReadTestFile(gSecondFile);
1.1235 + test.Printf(KMsg2,time);
1.1236 +
1.1237 + CorruptSecondFile();
1.1238 +
1.1239 + time = ReadTestFileVerif(gSecondFile,EFalse);
1.1240 + test.Printf(KMsg1,time);
1.1241 +
1.1242 + time = ReadTestFileVerif(gSecondFile,EFalse);
1.1243 + test.Printf(KMsg2,time);
1.1244 +
1.1245 + // Modify the file in disk, raw access
1.1246 + test.Next(_L("Overwrite file with raw access\n"));
1.1247 +
1.1248 + Formatting(gDrive,EFullFormat);
1.1249 +
1.1250 + r = TheFs.MkDirAll(gSessionPath);
1.1251 + if (r != KErrNone && r != KErrAlreadyExists)
1.1252 + {
1.1253 + test_KErrNone(r);
1.1254 + }
1.1255 +
1.1256 +
1.1257 + tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
1.1258 + test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
1.1259 +
1.1260 + time = ReadTestFile(gSecondFile);
1.1261 + test.Printf(KMsg1,time);
1.1262 +
1.1263 + time = ReadTestFile(gSecondFile);
1.1264 + test.Printf(KMsg2,time);
1.1265 +
1.1266 + CorruptSecondFileRaw();
1.1267 +
1.1268 + time = ReadTestFileVerif(gSecondFile,ETrue);
1.1269 + test.Printf(KMsg1,time);
1.1270 +
1.1271 + time = ReadTestFileVerif(gSecondFile,ETrue);
1.1272 + test.Printf(KMsg2,time);
1.1273 +
1.1274 +
1.1275 + r = DeleteAll(gSessionPath);
1.1276 + test_KErrNone(r);
1.1277 +
1.1278 + test.End();
1.1279 +}
1.1280 +
1.1281 +/** Creates the files to fill the read cache
1.1282 +
1.1283 + @param aFiles Number of files needed to fill the cache
1.1284 + @param aFileSize The file size
1.1285 +*/
1.1286 +LOCAL_C void CreateFiles(TInt aFiles, TInt aFileSize)
1.1287 +{
1.1288 + TInt i = 0, r = 0;
1.1289 + RFile file;
1.1290 + TBuf16<50> directory;
1.1291 +
1.1292 + TBuf16<50> path;
1.1293 + TBuf16<50> buffer(50);
1.1294 +
1.1295 + directory = gSessionPath;
1.1296 +
1.1297 + test.Printf(_L("Creating %d files for filling the cache (size %d)\n"), aFiles, aFileSize);
1.1298 +
1.1299 + // create a big buffer to speed things up
1.1300 + HBufC8* bigBuf = NULL;
1.1301 + const TInt KBigBifferSize = 32 * 1024;
1.1302 + TRAPD(res,bigBuf = HBufC8::NewL(KBigBifferSize));
1.1303 + test(res == KErrNone && bigBuf != NULL);
1.1304 +
1.1305 + TPtr8 bigBufWritePtr(NULL, 0);
1.1306 + bigBufWritePtr.Set(bigBuf->Des());
1.1307 + FillBuffer(bigBufWritePtr, KBigBifferSize, 'A');
1.1308 +
1.1309 +
1.1310 + i = 0;
1.1311 + while(i < aFiles)
1.1312 + {
1.1313 + if (i % 10 == 0)
1.1314 + test.Printf(_L("Creating file %d of %d...\r"), i, aFiles);
1.1315 + FileNameGen(buffer, 8, i+3) ;
1.1316 + path = directory;
1.1317 + path.Append(buffer);
1.1318 +
1.1319 + // delete file first to ensure it's contents are not in the cache (file may be on the closed file queue)
1.1320 + r = TheFs.Delete(path);
1.1321 + test(r == KErrNone || r == KErrNotFound);
1.1322 +
1.1323 + r = file.Create(TheFs,path,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
1.1324 + if(r == KErrAlreadyExists)
1.1325 + r = file.Open(TheFs,path,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
1.1326 + TInt j = 0;
1.1327 + while(j < aFileSize)
1.1328 + {
1.1329 + bigBufWritePtr.SetLength(Min(KBigBifferSize, aFileSize - j));
1.1330 + r = file.Write(bigBufWritePtr);
1.1331 + test_KErrNone(r);
1.1332 + j += bigBufWritePtr.Length();
1.1333 + }
1.1334 +
1.1335 + file.Close();
1.1336 + i++;
1.1337 + }
1.1338 + test.Printf(_L("\nFiles created\n"));
1.1339 + delete bigBuf;
1.1340 +}
1.1341 +
1.1342 +/** Fills the read cache
1.1343 +
1.1344 + @param aFile Array of files needed to fill the cache
1.1345 + @param aFiles Number of files needed to fill the cache
1.1346 + @param aFileSize The file size
1.1347 +*/
1.1348 +LOCAL_C void FillCache(RFile aFile[KFilesNeededToFillCache], TInt aFiles, TInt aFileSize)
1.1349 +{
1.1350 + TInt i = 0, r = 0;
1.1351 + TBuf16<50> directory;
1.1352 +
1.1353 + TBuf16<50> path;
1.1354 + TBuf16<50> buffer(50);
1.1355 + HBufC8* buf = NULL;
1.1356 + TPtr8 bufPtr(NULL, 0);
1.1357 +
1.1358 + TRAPD(res,buf = HBufC8::NewL(2));
1.1359 + test(res == KErrNone && buf != NULL);
1.1360 + bufPtr.Set(buf->Des());
1.1361 +
1.1362 + directory = gSessionPath;
1.1363 +
1.1364 + i = 0;
1.1365 + while(i < aFiles)
1.1366 + {
1.1367 + FileNameGen(buffer, 8, i+3) ;
1.1368 + path = directory;
1.1369 + path.Append(buffer);
1.1370 + r = aFile[i].Open(TheFs,path,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
1.1371 + test_KErrNone(r);
1.1372 +
1.1373 + TInt j = 0;
1.1374 + while(j < aFileSize)
1.1375 + {
1.1376 + r = aFile[i].Read(j,bufPtr);
1.1377 + test_KErrNone(r);
1.1378 + j += 4*KOneK;
1.1379 + }
1.1380 +
1.1381 + i++;
1.1382 + }
1.1383 +
1.1384 + delete buf;
1.1385 + test.Printf(_L("Cache filled\n"));
1.1386 +}
1.1387 +
1.1388 +/** Fills the default cache
1.1389 +
1.1390 +*/
1.1391 +LOCAL_C void TestFillCache()
1.1392 +{
1.1393 + TInt nFiles = KFilesNeededToFillCache;
1.1394 + TInt fSize = KDefaultCacheSize;
1.1395 + RFile file[KFilesNeededToFillCache];
1.1396 +
1.1397 + if(gMediaSize> ((fSize * nFiles)+gSecondFileSize+gFirstFileSize))
1.1398 + {
1.1399 + test.Start(_L("Creating files for filling the cache\n"));
1.1400 + CreateFiles(nFiles,fSize);
1.1401 +#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1.1402 + // get number of items on Page Cache
1.1403 + TFileCacheStats startPageCacheStats;
1.1404 + TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
1.1405 + test(r==KErrNone || r == KErrNotSupported);
1.1406 + test.Printf(_L("Number of page cache lines on free list at beginning=%d\n"),startPageCacheStats.iFreeCount);
1.1407 + test.Printf(_L("Number of page cache lines on used list at beginning=%d\n"),startPageCacheStats.iUsedCount);
1.1408 + test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
1.1409 +#endif
1.1410 + FillCache(file,nFiles,fSize);
1.1411 +
1.1412 +#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1.1413 + // get number of items on Page Cache
1.1414 + r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
1.1415 + test(r==KErrNone || r == KErrNotSupported);
1.1416 + test.Printf(_L("Number of page cache lines on free list at end=%d\n"),startPageCacheStats.iFreeCount);
1.1417 + test.Printf(_L("Number of page cache lines on used list at end=%d\n"),startPageCacheStats.iUsedCount);
1.1418 + test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
1.1419 +#endif
1.1420 + TestSimpleRead();
1.1421 +
1.1422 + TInt i = 0;
1.1423 + while( i < KFilesNeededToFillCache )
1.1424 + {
1.1425 + file[i++].Close();
1.1426 + }
1.1427 +
1.1428 + test.End();
1.1429 + }
1.1430 + else
1.1431 + test.Printf(_L("Skipping the fill of the cache due to lack of space in the current drive\n"));
1.1432 +}
1.1433 +
1.1434 +/** Overflow-safe tick deltas
1.1435 +
1.1436 +*/
1.1437 +static TInt64 TicksToMsec(TUint32 aInitTicks, TUint32 aFinalTicks, TInt aFastCounterFreq)
1.1438 + {
1.1439 + TUint32 timeDelta;
1.1440 + if (aFinalTicks >= aInitTicks)
1.1441 + timeDelta = aFinalTicks - aInitTicks;
1.1442 + else
1.1443 + timeDelta = aFinalTicks + (KMaxTUint32 - aInitTicks); // must've wrapped
1.1444 +
1.1445 + return TInt64(timeDelta) * TInt64(1000000) / TInt64(aFastCounterFreq);
1.1446 + }
1.1447 +
1.1448 +/** Read three blocks and waits for the read ahead on the File Server to do its job
1.1449 +
1.1450 +*/
1.1451 +LOCAL_C void TestReadAhead()
1.1452 +{
1.1453 + TInt r = 0,tcreate;
1.1454 + RFile fileRead;
1.1455 + HBufC8* dummy = NULL;
1.1456 + TPtr8 dummyPtr(NULL, 0);
1.1457 +
1.1458 + TUint32 initTicks = 0;
1.1459 + TUint32 finalTicks = 0;
1.1460 + TTimeIntervalMicroSeconds timeTakenReadFirst(0);
1.1461 + TTimeIntervalMicroSeconds timeTakenReadSubsequent(0);
1.1462 +
1.1463 + // On NAND/FAT and NOR/LFFS drives, due to the lack of DMA support, the read-ahead is likely to happen
1.1464 + // BEFORE control is returned to this test app - for NAND this could be fixed by adding
1.1465 + // "FileCacheReadAsync OFF" to the estart.txt file, but we can't do this on the integrator as it has no
1.1466 + // estart.txt file. Also, we can't set "FileCacheReadAsync OFF" for LFFS as it kills the LFFS background
1.1467 + // processing (!)
1.1468 + // So... it's only really worth testing on MMC.
1.1469 + _LIT(KFATName,"FAT");
1.1470 + TDriveInfo driveInfo;
1.1471 + test(TheFs.Drive(driveInfo, gDrive) == KErrNone);
1.1472 + TFileName fileSystem;
1.1473 + r = TheFs.FileSystemName(fileSystem, gDrive);
1.1474 + fileSystem.UpperCase();
1.1475 + test((r==KErrNone)||(r==KErrNotFound));
1.1476 + // ONLY test on MMC
1.1477 + if ((driveInfo.iType != EMediaHardDisk) || (fileSystem.Compare(KFATName) != 0))
1.1478 + {
1.1479 + test.Printf(_L("Skipping read-ahead testing (drive is not MMC)...\n"));
1.1480 + return;
1.1481 + }
1.1482 +
1.1483 + //--Find out if the drive is sync/async at this point and print information
1.1484 + TPckgBuf<TBool> drvSyncBuf;
1.1485 + r = TheFs.QueryVolumeInfoExt(gDrive, EIsDriveSync, drvSyncBuf);
1.1486 + test(r == KErrNone);
1.1487 + const TBool bDrvSync = drvSyncBuf();
1.1488 + if(bDrvSync)
1.1489 + test.Printf(_L("Drive D: is synchronous\n"));
1.1490 + else
1.1491 + test.Printf(_L("Drive D: is asynchronous\n"));
1.1492 +
1.1493 + // use a fast counter as this is more accurate than using TTime
1.1494 + TInt fastCounterFreq;
1.1495 + r = HAL::Get(HAL::EFastCounterFrequency, fastCounterFreq);
1.1496 + test(r == KErrNone);
1.1497 + test.Printf(_L("HAL::EFastCounterFrequency %d\n"), fastCounterFreq);
1.1498 +
1.1499 + // Bind this thread to CPU 0. This is so that timer deltas don't drift from
1.1500 + // scheduling - else, it causes spurious failures.
1.1501 + if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0) > 1)
1.1502 + (void)UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)0, 0);
1.1503 +
1.1504 + const TInt KReadLen = 28 * KOneK;
1.1505 +
1.1506 + TRAPD(res,dummy = HBufC8::NewL(KReadLen));
1.1507 + test(res == KErrNone && dummy != NULL);
1.1508 +
1.1509 + dummyPtr.Set(dummy->Des());
1.1510 +
1.1511 + test.Start(_L("Creating test file..."));
1.1512 +
1.1513 +
1.1514 + tcreate = WriteTestFile(gFirstFile, gFirstFileSize, ETrue);
1.1515 + test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
1.1516 +
1.1517 + r = fileRead.Open(TheFs,gFirstFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOn);
1.1518 + test_KErrNone(r);
1.1519 +
1.1520 + // Read #1
1.1521 + test.Printf(_L("Issuing read #1...\n"));
1.1522 + initTicks = User::FastCounter();
1.1523 + r = fileRead.Read(dummyPtr);
1.1524 + finalTicks = User::FastCounter();
1.1525 + test_KErrNone(r);
1.1526 +
1.1527 + timeTakenReadFirst = TicksToMsec(initTicks, finalTicks, fastCounterFreq);
1.1528 + test.Printf(_L("first read time %d \n"), I64LOW(timeTakenReadFirst.Int64()));
1.1529 +
1.1530 + // Read #2
1.1531 + test.Printf(_L("Issuing read #2...\n"));
1.1532 + r = fileRead.Read(dummyPtr);
1.1533 +
1.1534 + // Read #3
1.1535 + test.Printf(_L("Issuing read #3......resulting in read-ahead #1\n"));
1.1536 + r = fileRead.Read(dummyPtr);
1.1537 +
1.1538 + // Wait for the read ahead #1 to be done - this should be approx the same size as previous read (KReadLen)
1.1539 + test.Printf(_L("Wait for read-ahead #1...\n"));
1.1540 + User::After(I64LOW(timeTakenReadFirst.Int64()) * 3 / 2);
1.1541 +
1.1542 +
1.1543 + test.Printf(_L("Issuing read #4...resulting in read-ahead #2\n"));
1.1544 + initTicks = User::FastCounter();
1.1545 + r = fileRead.Read(dummyPtr);
1.1546 + finalTicks = User::FastCounter();
1.1547 + test_KErrNone(r);
1.1548 + timeTakenReadSubsequent = TicksToMsec(initTicks, finalTicks, fastCounterFreq);
1.1549 +
1.1550 + test.Printf(_L("read time: %d \n"), I64LOW(timeTakenReadSubsequent.Int64()));
1.1551 +
1.1552 +#if !defined(__WINS__)
1.1553 + // NB the read-ahead on LFFS occurs "synchronously" i.e. it occurs before control is returned
1.1554 + // to the caller. However it's not a good idea to mark the drive as synchronous (FileCacheReadAsync OFF)
1.1555 + // as this causes the drive thread's priority to be lowered which kills the LFFS background processing (!)
1.1556 + if (gPagedRom)
1.1557 + test.Printf(_L("Skipping timing test on paged ROM\n"));
1.1558 + else
1.1559 + test(timeTakenReadSubsequent.Int64() < timeTakenReadFirst.Int64());
1.1560 +#endif
1.1561 +
1.1562 + // The read ahead #2 should now be in progress - this should be approx KReadLen * 2
1.1563 + // so this read will take result in the next read taking longer than normal (about double)
1.1564 + test.Printf(_L("Issuing read #5......resulting in read-ahead #3\n"));
1.1565 + initTicks = User::FastCounter();
1.1566 + r = fileRead.Read(dummyPtr);
1.1567 + finalTicks = User::FastCounter();
1.1568 + test_KErrNone(r);
1.1569 + timeTakenReadSubsequent = TicksToMsec(initTicks, finalTicks, fastCounterFreq);
1.1570 + test.Printf(_L("read time: %d\n"), I64LOW(timeTakenReadSubsequent.Int64()));
1.1571 +
1.1572 +
1.1573 + // this read should take a long time, so don't test
1.1574 +//#if !defined(__WINS__)
1.1575 +// test(gTimeTakenReadBlockFile.Int64() < gTimeTakenBigFile.Int64());
1.1576 +//#endif
1.1577 +
1.1578 + // The third read should be very quick as the previous read-ahead should have already buffered the data
1.1579 + test.Printf(_L("Issuing read #6......resulting in read-ahead #4\n"));
1.1580 + initTicks = User::FastCounter();
1.1581 + r = fileRead.Read(dummyPtr);
1.1582 + finalTicks = User::FastCounter();
1.1583 + test_KErrNone(r);
1.1584 + timeTakenReadSubsequent = TicksToMsec(initTicks, finalTicks, fastCounterFreq);
1.1585 + test.Printf(_L("read time: %d\n"), I64LOW(timeTakenReadSubsequent.Int64()));
1.1586 +
1.1587 +
1.1588 +#if !defined(__WINS__)
1.1589 + if (gPagedRom)
1.1590 + test.Printf(_L("Skipping timing test on paged ROM\n"));
1.1591 + else
1.1592 + test(timeTakenReadSubsequent.Int64() < timeTakenReadFirst.Int64());
1.1593 +#endif
1.1594 +
1.1595 +
1.1596 + fileRead.Close();
1.1597 +
1.1598 + r = DeleteAll(gSessionPath);
1.1599 + test_KErrNone(r);
1.1600 +
1.1601 + delete dummy;
1.1602 + test.End();
1.1603 +
1.1604 +}
1.1605 +
1.1606 +/** Main tests function
1.1607 +*/
1.1608 +GLDEF_C void CallTestsL()
1.1609 + {
1.1610 +#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1.1611 + test.Printf(_L("Disabling Lock Fail simulation ...\n"));
1.1612 + // turn OFF lock failure mode
1.1613 + TBool simulatelockFailureMode = EFalse;
1.1614 + TInt r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
1.1615 + test (r == KErrNone);
1.1616 +#endif
1.1617 +
1.1618 + TBuf16<45> dir;
1.1619 +
1.1620 + RProcess().SetPriority(EPriorityBackground);
1.1621 +
1.1622 + // FileNames/File generation
1.1623 + test.Start(_L("Preparing the environmnet\n"));
1.1624 + FileNameGen(gFirstFile, 8, gNextFile++);
1.1625 + FileNameGen(gSecondFile, 8, gNextFile++);
1.1626 + dir = gSessionPath;
1.1627 + dir.Append(gFirstFile);
1.1628 + gFirstFile = dir;
1.1629 + dir = gSessionPath;
1.1630 + dir.Append(gSecondFile);
1.1631 + gSecondFile = dir;
1.1632 +
1.1633 +
1.1634 + TRAPD(res,gBuf = HBufC8::NewL(KBlockSize+1));
1.1635 + test(res == KErrNone && gBuf != NULL);
1.1636 +
1.1637 + gBufWritePtr.Set(gBuf->Des());
1.1638 + FillBuffer(gBufWritePtr, KBlockSize, 'A');
1.1639 +
1.1640 + TRAPD(res2,gBufSec = HBufC8::NewL(KBlockSize+1));
1.1641 + test(res2 == KErrNone && gBufSec != NULL);
1.1642 + gBufReadPtr.Set(gBufSec->Des());
1.1643 +
1.1644 + test.Next(_L("Negative test\n"));
1.1645 + TestNegative();
1.1646 +
1.1647 + test.Next(_L("Simple cases, use of the cache from same location/different"));
1.1648 + TestSimpleRead();
1.1649 +
1.1650 + test.Next(_L("Repeated reads, same file\n"));
1.1651 + TestRepeatedRead();
1.1652 +
1.1653 + test.Next(_L("Read ahead testing\n"));
1.1654 + TestReadAhead();
1.1655 +
1.1656 + test.Next(_L("Concurrent read cases\n"));
1.1657 + TestConcurrent();
1.1658 +
1.1659 + test.Next(_L("Fill the cache, boundary testing\n"));
1.1660 + TestFillCache();
1.1661 +
1.1662 + test.End();
1.1663 + delete gBuf;
1.1664 + delete gBufSec;
1.1665 +
1.1666 +#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
1.1667 + // turn lock failure mode back ON (if enabled)
1.1668 + simulatelockFailureMode = ETrue;
1.1669 + r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
1.1670 + test (r == KErrNone);
1.1671 +#endif
1.1672 +
1.1673 + }
1.1674 +
1.1675 +/** Initialises semaphores and call the tests
1.1676 +*/
1.1677 +LOCAL_C void DoTests()
1.1678 + {
1.1679 + TInt r = 0;
1.1680 +
1.1681 + r = client.CreateLocal(0);
1.1682 + test_KErrNone(r);
1.1683 +
1.1684 + r = gSync.CreateLocal(0);
1.1685 + test_KErrNone(r);
1.1686 +
1.1687 +
1.1688 + r = TheFs.SetSessionPath(gSessionPath);
1.1689 + test_KErrNone(r);
1.1690 +
1.1691 + r = TheFs.MkDirAll(gSessionPath);
1.1692 + if (r != KErrNone && r != KErrAlreadyExists)
1.1693 + {
1.1694 + test_KErrNone(r);
1.1695 + }
1.1696 + TheFs.ResourceCountMarkStart();
1.1697 + TRAP(r,CallTestsL());
1.1698 + if (r == KErrNone)
1.1699 + TheFs.ResourceCountMarkEnd();
1.1700 + else
1.1701 + {
1.1702 + test_KErrNone(r);
1.1703 + }
1.1704 + }
1.1705 +
1.1706 +/** Determines the space that can be used for the files
1.1707 +
1.1708 +*/
1.1709 +TBool CheckForDiskSize()
1.1710 +{
1.1711 + TVolumeInfo volInfo;
1.1712 + TInt r = TheFs.Volume(volInfo, gDrive);
1.1713 + test_KErrNone(r);
1.1714 + gMediaSize = volInfo.iSize;
1.1715 + gSecondFileSize = KBlockSize*92;
1.1716 + gFirstFileSize = KBlockSize*(256);
1.1717 + while(((2*gFirstFileSize)+KOneMeg) > gMediaSize )
1.1718 + {
1.1719 + gFirstFileSize -= (2*KBlockSize);
1.1720 + }
1.1721 +
1.1722 + TReal32 small = (TReal32)(gSecondFileSize/KOneK);
1.1723 + TReal32 big = (TReal32)(gFirstFileSize/KOneK);
1.1724 +
1.1725 + test.Printf(_L("Test File: %.2f KB\n"), small );
1.1726 + test.Printf(_L("Too big for the cache file: %.2f KB (%.2f MB)\n"), big, big / KOneK );
1.1727 +
1.1728 + if(gFirstFileSize < gSecondFileSize)
1.1729 + return EFalse;
1.1730 + else
1.1731 + return ETrue;
1.1732 +}
1.1733 +
1.1734 +/** Main function
1.1735 +
1.1736 + @return KErrNone if everything was ok, panics otherwise
1.1737 +*/
1.1738 +GLDEF_C TInt E32Main()
1.1739 + {
1.1740 + // Determine whether this is a paged ROM -
1.1741 + // if it is we bypass some of the timimg tests as the default paging ROMs have a deliberately
1.1742 + // small pool of pages (in order to stress the system) and reading things through the file cache
1.1743 + // in this "artificial" environment can cause code to be evicted which can result in the read timings
1.1744 + // going AWOL. In a more real-world environment, file caching should turn itself off if the amount of
1.1745 + // memory falls below a threshold.
1.1746 +#if !defined(__WINS__)
1.1747 + TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
1.1748 + gPagedRom = romHeader->iPageableRomStart ? (TBool)ETrue : (TBool)EFalse;
1.1749 +#endif
1.1750 +
1.1751 + RThread t;
1.1752 + gMainThreadId = t.Id();
1.1753 +
1.1754 + CTrapCleanup* cleanup;
1.1755 + cleanup = CTrapCleanup::New();
1.1756 +
1.1757 + __UHEAP_MARK;
1.1758 + test.Start(_L("Starting tests... T_RCACHE"));
1.1759 + parseCommandLine();
1.1760 +
1.1761 + TInt r = TheFs.Connect();
1.1762 + test_KErrNone(r);
1.1763 +
1.1764 + TDriveInfo info;
1.1765 + TVolumeInfo volInfo;
1.1766 + r = TheFs.Drive(info,gDrive);
1.1767 + test_KErrNone(r);
1.1768 +
1.1769 + if(info.iMediaAtt&KMediaAttVariableSize)
1.1770 + {
1.1771 + test.Printf(_L("Tests skipped in RAM drive\n"));
1.1772 + goto out;
1.1773 + }
1.1774 +
1.1775 + r = TheFs.Volume(volInfo, gDrive);
1.1776 + if (r == KErrNotReady)
1.1777 + {
1.1778 + if (info.iType == EMediaNotPresent)
1.1779 + test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest);
1.1780 + else
1.1781 + test.Printf(_L("%c: medium found (type %d) but drive not ready\nPrevious test may have hung; else, check hardware.\n"), (TUint)gDriveToTest, (TInt)info.iType);
1.1782 + }
1.1783 + else if (r == KErrCorrupt)
1.1784 + {
1.1785 + test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest);
1.1786 + }
1.1787 + test_KErrNone(r);
1.1788 +
1.1789 + if(!(volInfo.iFileCacheFlags & (EFileCacheReadEnabled | EFileCacheReadAheadEnabled)))
1.1790 + {
1.1791 + test.Printf(_L("Skipping tests, Read caching not enabled in this drive\n"));
1.1792 + goto out;
1.1793 + }
1.1794 +
1.1795 + if (((volInfo.iDrive.iMediaAtt & KMediaAttFormattable)))
1.1796 + Formatting(gDrive,ESpecialFormat);
1.1797 +
1.1798 + if(CheckForDiskSize())
1.1799 + {
1.1800 + DoTests();
1.1801 + }
1.1802 + else
1.1803 + {
1.1804 + test.Printf(_L("Skipping tests due to lack of space to perform them in this drive\n"));
1.1805 + }
1.1806 +out:
1.1807 + test.End();
1.1808 +
1.1809 + TheFs.Close();
1.1810 + test.Close();
1.1811 +
1.1812 + __UHEAP_MARKEND;
1.1813 + delete cleanup;
1.1814 + return(KErrNone);
1.1815 + }
1.1816 +