1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/debug/t_perflogger.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,579 @@
1.4 +// Copyright (c) 2005-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 +// Kernel Performance Logger test
1.18 +// Uses helper LDD for performing actual logging from the kernel side.
1.19 +// See
1.20 +//
1.21 +//
1.22 +
1.23 +/**
1.24 + @file
1.25 +*/
1.26 +
1.27 +
1.28 +#include <e32std.h>
1.29 +#include <e32std_private.h>
1.30 +#include <e32cons.h>
1.31 +#include <e32test.h>
1.32 +#include <e32math.h>
1.33 +
1.34 +
1.35 +#include "t_perflogger.h"
1.36 +#include "t_perflogger_drv.h"
1.37 +
1.38 +
1.39 +//-------------------------------------------------------------------------------------
1.40 +
1.41 +//-- logging subcategoty test tags
1.42 +const TUint8 KLogSubCat_UserThread = 0x11;
1.43 +const TUint8 KLogSubCat_KernelThread = 0x12;
1.44 +const TUint8 KLogSubCat_ISR = 0x13;
1.45 +const TUint8 KLogSubCat_IDFC = 0x14;
1.46 +
1.47 +
1.48 +//-------------------------------------------------------------------------------------
1.49 +
1.50 +RTest test(_L("T_PerfLogger"));
1.51 +TInt64 rndSeed;
1.52 +
1.53 +//-------------------------------------------------------------------------------------
1.54 +
1.55 +/**
1.56 +Print out the logging record.
1.57 +@param aTraceLayout unrolled trace record structure
1.58 +*/
1.59 +void PrintTraceRecord(const TTraceLayout& aTraceLayout)
1.60 + {
1.61 + TBuf<256> printBuf;
1.62 +
1.63 + printBuf.Format(_L("Record: Size:%d, Flags:0x%02x, Cat:%d, SubCat:%d "), aTraceLayout.iSize, aTraceLayout.iFlags, aTraceLayout.iCategory, aTraceLayout.iSubCategory);
1.64 +
1.65 + TUint flags = aTraceLayout.iFlags;
1.66 +
1.67 + if(flags&(BTrace::EHeader2Present))
1.68 + printBuf.AppendFormat(_L("Header2:0x%08x "), aTraceLayout.iHeader2);
1.69 +
1.70 + if(flags & (BTrace::ETimestampPresent))
1.71 + printBuf.AppendFormat(_L("Timestamp:0x%x "), aTraceLayout.iTimestamp);
1.72 +
1.73 + if(flags & (BTrace::ETimestamp2Present))
1.74 + printBuf.AppendFormat(_L("Timestamp2:0x%x "), aTraceLayout.iTimestamp2);
1.75 +
1.76 + if(flags & (BTrace::EContextIdPresent))
1.77 + printBuf.AppendFormat(_L("Context:0x%08x "), aTraceLayout.iContext);
1.78 +
1.79 + if(flags & (BTrace::EPcPresent))
1.80 + printBuf.AppendFormat(_L("PC: 0x%08x "), aTraceLayout.iPC);
1.81 +
1.82 + if(flags & (BTrace::EExtraPresent))
1.83 + printBuf.AppendFormat(_L("Extra: 0x%08x "), aTraceLayout.iExtra);
1.84 +
1.85 + printBuf.Append(_L("| "));
1.86 + for(TInt i=0; i< aTraceLayout.iDataWords; ++i)
1.87 + {
1.88 + printBuf.AppendFormat(_L(" 0x%08x"), aTraceLayout.ipData[i]);
1.89 + }
1.90 +
1.91 + printBuf.Append(_L("\n"));
1.92 + test.Printf(printBuf);
1.93 +
1.94 + }
1.95 +
1.96 +//-------------------------------------------------------------------------------------
1.97 +
1.98 +/**
1.99 + Get logging trace from the kernel trace engine and optionally check if it corresponds to the
1.100 + TTestLogCtrl structure fields. Actually, the logging trace in our case shall be the result of the
1.101 + test helper LDD worr, that in turn, is controlled by the data in TTestLogCtrl structure.
1.102 +
1.103 + @param aTrace ref. to the kernel trace engine LDD.
1.104 + @param apControlStruct if not NULL obtained trace fields checked against fields of this structure.
1.105 +
1.106 +*/
1.107 +void GetParseRecordData(RBTrace& aTrace, const TTestLogCtrl* apControlStruct = NULL)
1.108 + {
1.109 + TUint8* record;
1.110 + TTraceLayout traceLayout;
1.111 +
1.112 + for(TInt i=0; ;++i)
1.113 + {
1.114 + //-- get raw trace record
1.115 + TInt dataSize = aTrace.GetData(record);
1.116 +
1.117 + if(i != 0 && !dataSize)
1.118 + break; //-- no more data
1.119 +
1.120 + //-- check if we get log data at all at the very beginning
1.121 + if(i == 0 && !dataSize)
1.122 + {
1.123 + if(!apControlStruct)
1.124 + {//-- it's ok, no check
1.125 + break;
1.126 + }
1.127 + else
1.128 + {//-- panic if there is no log data, but we are required to get some.
1.129 + if(apControlStruct->iLogsNum > 0)
1.130 + {
1.131 + test.Printf(_L("GetParseRecordData() No trace data found!\n"));
1.132 + test(0);
1.133 + }
1.134 + }
1.135 + }
1.136 +
1.137 +
1.138 + TUint8* end = record+dataSize;
1.139 + TUint8* currPos = record;
1.140 + TInt nRecords = 0;
1.141 + TUint nBytes = 0;
1.142 +
1.143 + //-- parser the record, print out fields and optionally check the correspondence to the fields of the control structure.
1.144 + for(; currPos<end; currPos+=nBytes)
1.145 + {
1.146 +
1.147 + nBytes = ParseTraceRecord(currPos ,traceLayout);
1.148 + test(nBytes >0 );
1.149 +
1.150 + //-- skip possible loggings that we didn't make
1.151 + if(traceLayout.iCategory != BTrace::EKernPerfLog)
1.152 + continue;
1.153 +
1.154 + ++nRecords;
1.155 +
1.156 + //-- print the record out
1.157 + PrintTraceRecord(traceLayout);
1.158 +
1.159 + //-- check the obtained record structure
1.160 + if(apControlStruct)
1.161 + {
1.162 + test(traceLayout.iCategory == apControlStruct->iCategory);
1.163 + test(traceLayout.iSubCategory == apControlStruct->iSubCategory);
1.164 +
1.165 + if(traceLayout.iDataWords > 1) //-- we have at least 1 word of user data (1 is for TickCount)
1.166 + test(traceLayout.ipData[0] == apControlStruct->iUserData);
1.167 +
1.168 + if(traceLayout.iDataWords > 2) //-- we have 2 words of user data (1 is for TickCount)
1.169 + test(traceLayout.ipData[1] == apControlStruct->iUserData2);
1.170 +
1.171 + }
1.172 +
1.173 + }
1.174 +
1.175 + //-- check number of trace records obtained
1.176 + if(apControlStruct)
1.177 + {
1.178 + test(nRecords == apControlStruct->iLogsNum);
1.179 + }
1.180 +
1.181 + //-- release data buffer.
1.182 + aTrace.DataUsed();
1.183 + }
1.184 + }
1.185 +
1.186 +
1.187 +//---------------------------------------------------------------------------------
1.188 +
1.189 +/**
1.190 + Parse logging record, converting it from the raw representation to the unrolled data
1.191 + structure.
1.192 +
1.193 + @param apRecord points to the buffer with the raw trace record
1.194 + @param aTraceLayout here parsed record will bre returned
1.195 +
1.196 + @return sise of the record, bytes
1.197 +*/
1.198 +TUint ParseTraceRecord(const TUint8* apRecord, TTraceLayout& aTraceLayout)
1.199 + {
1.200 + aTraceLayout.iSize = apRecord[BTrace::ESizeIndex];
1.201 + aTraceLayout.iFlags = apRecord[BTrace::EFlagsIndex];
1.202 + aTraceLayout.iCategory = apRecord[BTrace::ECategoryIndex];
1.203 + aTraceLayout.iSubCategory = apRecord[BTrace::ESubCategoryIndex];
1.204 +
1.205 + const TUint flags= aTraceLayout.iFlags;
1.206 + TInt size = aTraceLayout.iSize;
1.207 + const TUint32* pData = (const TUint32*)(apRecord+4);
1.208 +
1.209 + size -= 4; //-- count header
1.210 +
1.211 + //-- process header flags and appropriate fields of the record
1.212 + if(flags&(BTrace::EHeader2Present))
1.213 + {
1.214 + aTraceLayout.iHeader2 = *pData++;
1.215 + size -= sizeof(TUint32);
1.216 + test(size >= 0);
1.217 + }
1.218 +
1.219 + if(flags & (BTrace::ETimestampPresent))
1.220 + {
1.221 + aTraceLayout.iTimestamp = *pData++;
1.222 + size -= sizeof(TUint32);
1.223 + test(size >= 0);
1.224 + }
1.225 +
1.226 + if(flags & (BTrace::ETimestamp2Present))
1.227 + {
1.228 + aTraceLayout.iTimestamp2 = *pData++;
1.229 + size -= sizeof(TUint32);
1.230 + test(size >= 0);
1.231 + }
1.232 +
1.233 + if(flags & (BTrace::EContextIdPresent))
1.234 + {
1.235 + aTraceLayout.iContext = *pData++;
1.236 + size -= sizeof(TUint32);
1.237 + test(size >= 0);
1.238 + }
1.239 +
1.240 + if(flags & (BTrace::EPcPresent))
1.241 + {
1.242 + aTraceLayout.iPC = *pData++;
1.243 + size -= sizeof(TUint32);
1.244 + test(size >= 0);
1.245 + }
1.246 +
1.247 + if(flags & (BTrace::EExtraPresent))
1.248 + {
1.249 + aTraceLayout.iExtra = *pData++;
1.250 + size -= sizeof(TUint32);
1.251 + test(size >= 0);
1.252 + }
1.253 +
1.254 + //-- process user data if present
1.255 + test(size >= 0);
1.256 + test(size % sizeof(TUint32) == 0);
1.257 +
1.258 + aTraceLayout.iDataWords = size / sizeof(TUint32);
1.259 + aTraceLayout.ipData = (aTraceLayout.iDataWords!=0) ? pData : NULL;
1.260 +
1.261 + return aTraceLayout.iSize;
1.262 + }
1.263 +
1.264 +//---------------------------------------------------------------------------------
1.265 +//! @SYMTestCaseID KBASE-T_PERFLOGGER-0055
1.266 +//! @SYMTestType UT
1.267 +//! @SYMPREQ PREQ1030
1.268 +//! @SYMTestCaseDesc Tests logging from different contexts: user thread, ISR, Kernel thread and IDFC.
1.269 +//! The main functionality is performed by test heller LDD, "d_perflogger_test" that acually calls the logging function from different contexts
1.270 +//! following the commands from user application.
1.271 +//!
1.272 +//! @SYMTestActions 0 setup the data structures that specify the logging parameters.
1.273 +//! 1 call RKPLoggerTestHelper::MakeLogFromUserThread() this is a synchronous operation. Performs logging from the user thread context.
1.274 +//! 1.1 Parse the log record data and ensure that the logged information matches the data we passed to the helper LDD.
1.275 +//!
1.276 +//! 2 call RKPLoggerTestHelper::MakeLogFromISR() this is asynchronous operation. Performs logging from the ISR context.
1.277 +//! 2.1 Wait for operation to complete, validate the completion status.
1.278 +//! 2.2 Parse the log record data and ensure that the logged information matches the data we passed to the helper LDD.
1.279 +//!
1.280 +//!
1.281 +//! 3 call RKPLoggerTestHelper::MakeLogFromDFC() this is asynchronous operation. Performs logging from the Kernel thread context (DFC).
1.282 +//! 3.1 Wait for operation to complete, validate the completion status.
1.283 +//! 3.2 Parse the log record data and ensure that the logged information matches the data we passed to the helper LDD.
1.284 +//!
1.285 +//! 4 call RKPLoggerTestHelper::MakeLogFromIDFC() this is asynchronous operation. Performs logging from the IDFC.
1.286 +//! 4.1 Wait for operation to complete, validate the completion status.
1.287 +//! 4.2 Parse the log record data and ensure that the logged information matches the data we passed to the helper LDD.
1.288 +//!
1.289 +//! 5. Make scattered overlapped logging from ISR, DFC & IDFC simultaneously, ensure that this work.
1.290 +//!
1.291 +//! @SYMTestExpectedResults return if the performace logger behaves as expected, panic otherwise
1.292 +//! @SYMTestPriority High
1.293 +//! @SYMTestStatus Implemented
1.294 +//---------------------------------------------------------------------------------
1.295 +void TestPerfLogger(RBTrace &aTrace)
1.296 + {
1.297 + TInt nRes;
1.298 +
1.299 + const TUint32 KLogUserData = 0xBAAABEEF; //-- just for testing
1.300 + const TUint32 KLogUserData2 = 0x11FFDDCC; //-- just for testing
1.301 +
1.302 +
1.303 + test.Next(_L("testing kernel performance logger functionality\n"));
1.304 +
1.305 + RKPLoggerTestHelper testHelperLDD; //-- helper test driver
1.306 + CleanupClosePushL(testHelperLDD);
1.307 +
1.308 + nRes = testHelperLDD.Open(TVersion(1,0,1)); //-- open test helper ldd for a logger
1.309 + test(nRes == KErrNone);
1.310 +
1.311 + //---
1.312 + TTestLogCtrl logCtrl_UserThread;
1.313 + TTestLogCtrl logCtrl_ISR;
1.314 + TTestLogCtrl logCtrl_DFC;
1.315 + TTestLogCtrl logCtrl_IDFC;
1.316 +
1.317 +
1.318 + TRequestStatus rqStatLogFromISR;
1.319 + TRequestStatus rqStatLogFromDFC;
1.320 + TRequestStatus rqStatLogFromIDFC;
1.321 +
1.322 +
1.323 + //-- setup log control structures
1.324 + logCtrl_UserThread.iLogsNum = 3;
1.325 + logCtrl_UserThread.iCategory = BTrace::EKernPerfLog;
1.326 + logCtrl_UserThread.iSubCategory = KLogSubCat_UserThread;
1.327 + logCtrl_UserThread.iUserData = KLogUserData;
1.328 + logCtrl_UserThread.iUserData2 = KLogUserData2;
1.329 +
1.330 +
1.331 + logCtrl_ISR.iLogsNum = 3;
1.332 + logCtrl_ISR.iCategory = BTrace::EKernPerfLog;
1.333 + logCtrl_ISR.iSubCategory = KLogSubCat_ISR;
1.334 + logCtrl_ISR.iUserData = KLogUserData;
1.335 + logCtrl_ISR.iUserData2 = KLogUserData2;
1.336 +
1.337 +
1.338 + logCtrl_DFC.iLogsNum = 3;
1.339 + logCtrl_DFC.iCategory = BTrace::EKernPerfLog;
1.340 + logCtrl_DFC.iSubCategory = KLogSubCat_KernelThread;
1.341 + logCtrl_DFC.iUserData = KLogUserData;
1.342 + logCtrl_DFC.iUserData2 = KLogUserData2;
1.343 +
1.344 +
1.345 + logCtrl_IDFC.iLogsNum = 3;
1.346 + logCtrl_IDFC.iCategory = BTrace::EKernPerfLog;
1.347 + logCtrl_IDFC.iSubCategory = KLogSubCat_IDFC;
1.348 + logCtrl_IDFC.iUserData = KLogUserData;
1.349 + logCtrl_IDFC.iUserData2 = KLogUserData2;
1.350 +
1.351 +
1.352 +
1.353 + test.Printf(_L("Testing logging from user thread\n"));
1.354 + //============================================================
1.355 + //-- 1. make logging from user thread, this is a synchronous operation
1.356 + nRes = testHelperLDD.MakeLogFromUserThread(logCtrl_UserThread);
1.357 + test(nRes == KErrNone);
1.358 +
1.359 + //-- 1.1 check the results
1.360 + GetParseRecordData(aTrace, &logCtrl_UserThread);
1.361 +
1.362 +
1.363 + test.Printf(_L("Testing logging from ISR\n"));
1.364 + //============================================================
1.365 + //-- 2. make logging from ISR, this is asynchronous operation
1.366 + testHelperLDD.MakeLogFromISR(rqStatLogFromISR, logCtrl_ISR);
1.367 + User::WaitForRequest(rqStatLogFromISR);
1.368 + test(rqStatLogFromISR.Int() == KErrNone);
1.369 +
1.370 + //-- 2.1 check the results
1.371 + GetParseRecordData(aTrace, &logCtrl_ISR);
1.372 +
1.373 + test.Printf(_L("Testing logging from DFC\n"));
1.374 + //============================================================
1.375 + //-- 3. make logging from DFC kennel thread, this is asynchronous operation
1.376 + testHelperLDD.MakeLogFromDFC(rqStatLogFromDFC, logCtrl_DFC);
1.377 + User::WaitForRequest(rqStatLogFromDFC);
1.378 + test(rqStatLogFromDFC.Int() == KErrNone);
1.379 +
1.380 + //-- 3.1 check the results
1.381 + GetParseRecordData(aTrace, &logCtrl_DFC);
1.382 +
1.383 + test.Printf(_L("Testing logging from IDFC\n"));
1.384 + //============================================================
1.385 + //-- 4. make logging from IDFC, this is asynchronous operation
1.386 + testHelperLDD.MakeLogFromIDFC(rqStatLogFromIDFC, logCtrl_IDFC);
1.387 + User::WaitForRequest(rqStatLogFromIDFC);
1.388 + test(rqStatLogFromIDFC.Int() == KErrNone);
1.389 +
1.390 + //-- 4.1 check the results
1.391 + GetParseRecordData(aTrace, &logCtrl_IDFC);
1.392 +
1.393 +
1.394 + test.Printf(_L("Testing overlapped logging from ISR, DFC & IDFC\n"));
1.395 + //============================================================
1.396 + //-- 5. make logging from ISR, DFC and IDFC simultaneously
1.397 +
1.398 + //-- use random numbers for number and period of loggings
1.399 + logCtrl_ISR.iLogsNum = URnd(16)+1;
1.400 + logCtrl_ISR.iLogPeriodTick = URnd(20)+1;
1.401 +
1.402 + logCtrl_DFC.iLogsNum = URnd(16)+1;
1.403 + logCtrl_DFC.iLogPeriodTick = URnd(20)+1;
1.404 +
1.405 + logCtrl_IDFC.iLogsNum = URnd(16)+1;
1.406 + logCtrl_IDFC.iLogPeriodTick = URnd(20)+1;
1.407 +
1.408 + //-- start logging
1.409 + testHelperLDD.MakeLogFromISR(rqStatLogFromISR, logCtrl_ISR);
1.410 + testHelperLDD.MakeLogFromDFC(rqStatLogFromDFC, logCtrl_DFC);
1.411 + testHelperLDD.MakeLogFromIDFC(rqStatLogFromIDFC, logCtrl_IDFC);
1.412 +
1.413 + //-- wait for logging to finish
1.414 + User::WaitForRequest(rqStatLogFromISR);
1.415 + User::WaitForRequest(rqStatLogFromDFC);
1.416 + User::WaitForRequest(rqStatLogFromIDFC);
1.417 +
1.418 + GetParseRecordData(aTrace);
1.419 +
1.420 +
1.421 + CleanupStack::PopAndDestroy(1); //-- testHelperLDD
1.422 +
1.423 +}
1.424 +
1.425 +
1.426 +//---------------------------------------------------------------------------------
1.427 +//! @SYMTestCaseID KBASE-T_PERFLOGGER-0056
1.428 +//! @SYMTestType UT
1.429 +//! @SYMPREQ PREQ1030
1.430 +//! @SYMTestCaseDesc Test of PERF_LOG0, PERF_LOG1, PERF_LOG macros performed by helper LDD
1.431 +//! @SYMTestActions Calls helper LDD API that in turn implies using PERF_LOG0, PERF_LOG1, PERF_LOG macros by helper LDD
1.432 +//! @SYMTestExpectedResults return if the performace logger behaves as expected, panic otherwise
1.433 +//! @SYMTestPriority High
1.434 +//! @SYMTestStatus Implemented
1.435 +//---------------------------------------------------------------------------------
1.436 +void TestMacros(RBTrace &aTrace)
1.437 + {
1.438 + TInt nRes;
1.439 +
1.440 + const TUint32 KLogUserData = 0xBAAABEEF; //-- just for testing
1.441 + const TUint32 KLogUserData2 = 0x11FFDDCC; //-- just for testing
1.442 +
1.443 +
1.444 + test.Next(_L("Unit test for different macros\n"));
1.445 +
1.446 + RKPLoggerTestHelper testHelperLDD; //-- helper test driver
1.447 + CleanupClosePushL(testHelperLDD);
1.448 +
1.449 + nRes = testHelperLDD.Open(TVersion(1,0,1)); //-- open test helper ldd for a logger
1.450 + test(nRes == KErrNone);
1.451 +
1.452 + //---
1.453 + TTestLogCtrl logCtrl;
1.454 +
1.455 + //-- setup log control structures
1.456 + logCtrl.iLogsNum = 1;
1.457 + logCtrl.iCategory = BTrace::EKernPerfLog;
1.458 + logCtrl.iSubCategory = KLogSubCat_UserThread;
1.459 + logCtrl.iUserData = KLogUserData;
1.460 + logCtrl.iUserData2 = KLogUserData2;
1.461 +
1.462 + //-- make logging from user thread using different macros, PERF_LOG0, PERF_LOG1, PERF_LOG
1.463 + //-- see the helper driver
1.464 + nRes = testHelperLDD.TestDifferentMacros(logCtrl);
1.465 + test(nRes == KErrNone);
1.466 +
1.467 + //-- print out the results
1.468 + GetParseRecordData(aTrace);
1.469 +
1.470 +
1.471 + CleanupStack::PopAndDestroy(1); //-- testHelperLDD
1.472 +
1.473 + }
1.474 +
1.475 +//---------------------------------------------------------------------------------
1.476 +void MainL(void)
1.477 + {
1.478 + test.Start(_L("Kern Perf Logger tests"));
1.479 + Initialise();
1.480 +
1.481 +
1.482 + RBTrace trace;
1.483 + TInt error = trace.Open();
1.484 + test(error == KErrNone);
1.485 +
1.486 + trace.Empty();
1.487 + trace.SetFilter(BTrace::EThreadIdentification,0);
1.488 +
1.489 +
1.490 +
1.491 + //-- actually, for hardware platforms, the testing category and trace enabling
1.492 + //-- may be set up in appropriate "header.iby" file
1.493 + trace.SetMode(RBTrace::EEnable);
1.494 + trace.SetFilter(BTrace::EKernPerfLog, ETrue);
1.495 +
1.496 + //-- unit-test for PERF_LOG macros
1.497 + TestMacros(trace);
1.498 +
1.499 + //-- functionality test
1.500 + TestPerfLogger(trace);
1.501 +
1.502 + trace.Close();
1.503 +
1.504 + Finalise();
1.505 + test.End();
1.506 + }
1.507 +
1.508 +
1.509 +//---------------------------------------------------------------------------------
1.510 +//! @SYMTestCaseID KBASE-T_PERFLOGGER-0162
1.511 +//! @SYMTestType UT
1.512 +//! @SYMPREQ PREQ1030
1.513 +//! @SYMTestCaseDesc Load test helper LDD and check the result
1.514 +//! @SYMTestActions load specified LDD by calling User::LoadLogicalDevice()
1.515 +//! @SYMTestExpectedResults return if helper LDD is loaded OK, panic otherwise
1.516 +//! @SYMTestPriority High
1.517 +//! @SYMTestStatus Implemented
1.518 +//---------------------------------------------------------------------------------
1.519 +void Initialise()
1.520 + {
1.521 + rndSeed = Math::Random();
1.522 +
1.523 + //-- load device drivers
1.524 + TInt nRes;
1.525 +
1.526 + test.Printf(_L("Loading test helper LDD...\n"));
1.527 + nRes = User::LoadLogicalDevice(KPLoggerHelperTestDrv);
1.528 + test(nRes == KErrNone || nRes == KErrAlreadyExists);
1.529 + }
1.530 +
1.531 +/** Finalise environment */
1.532 +void Finalise(void)
1.533 + {
1.534 + }
1.535 +
1.536 +
1.537 +
1.538 +/**
1.539 + Main
1.540 +*/
1.541 +GLDEF_C TInt E32Main()
1.542 + {
1.543 + CTrapCleanup* cleanup=CTrapCleanup::New() ; // get clean-up stack
1.544 +
1.545 + TRAPD(r,MainL());
1.546 +
1.547 + delete cleanup ; // destroy clean-up stack
1.548 +
1.549 + return r;
1.550 +
1.551 + }
1.552 +
1.553 +//-------------------------------------------------------------------------------------
1.554 +
1.555 +TUint URnd(TUint aMin, TUint aMax)
1.556 + {
1.557 + test(aMin < aMax);
1.558 + TUint uRes;
1.559 +
1.560 + do
1.561 + {
1.562 + uRes = Math::Rand(rndSeed) % aMax;
1.563 + }while(uRes < aMin);
1.564 +
1.565 + return uRes;
1.566 + }
1.567 +
1.568 +TUint URnd(TUint aMax)
1.569 + {
1.570 + return Math::Rand(rndSeed) % aMax;
1.571 + }
1.572 +
1.573 +
1.574 +
1.575 +
1.576 +
1.577 +
1.578 +
1.579 +
1.580 +
1.581 +
1.582 +