os/kernelhwsrv/kerneltest/e32test/mmu/t_shbuf.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) 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
// e32test/mmu/t_shbuf.cpp
sl@0
    15
//
sl@0
    16
sl@0
    17
#define __E32TEST_EXTENSION__
sl@0
    18
sl@0
    19
#include <e32test.h>
sl@0
    20
#include <hal.h>
sl@0
    21
#include <e32svr.h>
sl@0
    22
#include <u32hal.h>
sl@0
    23
#include "d_shbuf.h"
sl@0
    24
#include <e32shbuf.h>
sl@0
    25
#include <e32def.h>
sl@0
    26
#include <e32def_private.h>
sl@0
    27
sl@0
    28
#ifdef TEST_CLIENT_THREAD
sl@0
    29
RTest test(_L("T_SHBUF_CLIENT"));
sl@0
    30
#else
sl@0
    31
RTest test(_L("T_SHBUF_OWN"));
sl@0
    32
#endif
sl@0
    33
sl@0
    34
RShPool P1; // User-side pool
sl@0
    35
RShPool P2; // Kernel-side pool
sl@0
    36
sl@0
    37
const TInt KTestPoolSizeInBytes = 1 << 20; // 1MB
sl@0
    38
const TInt BufferSize[] = {128, 853, 4096, 5051, 131072, 1, 0}; // Last element must be 0
sl@0
    39
sl@0
    40
const TInt* PtrBufSize;
sl@0
    41
sl@0
    42
RShBufTestChannel Ldd;
sl@0
    43
sl@0
    44
_LIT(KTestSlave, "SLAVE");
sl@0
    45
_LIT(KTestLowSpaceSemaphore, "LowSpaceSemaphore");
sl@0
    46
sl@0
    47
enum TTestSlave
sl@0
    48
	{
sl@0
    49
	ETestSlaveError,
sl@0
    50
	ETestSlaveNoDeallocation,
sl@0
    51
	};
sl@0
    52
sl@0
    53
enum TTestPoolType
sl@0
    54
	{
sl@0
    55
	ETestNonPageAligned,
sl@0
    56
	ETestPageAligned,
sl@0
    57
	ETestPageAlignedGrowing,
sl@0
    58
	};
sl@0
    59
sl@0
    60
TInt Log2(TInt aNum)
sl@0
    61
	{
sl@0
    62
	TInt res = -1;
sl@0
    63
	while(aNum)
sl@0
    64
		{
sl@0
    65
		res++;
sl@0
    66
		aNum >>= 1;
sl@0
    67
		}
sl@0
    68
	return res;
sl@0
    69
	}
sl@0
    70
sl@0
    71
TInt RoundUp(TInt aNum, TInt aAlignmentLog2)
sl@0
    72
	{
sl@0
    73
	if (aNum % (1 << aAlignmentLog2) == 0)
sl@0
    74
		{
sl@0
    75
		return aNum;
sl@0
    76
		}
sl@0
    77
	return (aNum & ~((1 << aAlignmentLog2) - 1)) + (1 << aAlignmentLog2);
sl@0
    78
	}
sl@0
    79
sl@0
    80
void LoadDeviceDrivers()
sl@0
    81
	{
sl@0
    82
	TInt r;
sl@0
    83
	#ifdef TEST_CLIENT_THREAD
sl@0
    84
	r= User::LoadLogicalDevice(_L("D_SHBUF_CLIENT.LDD"));
sl@0
    85
	if (r != KErrAlreadyExists)
sl@0
    86
		{
sl@0
    87
		test_KErrNone(r);
sl@0
    88
		}
sl@0
    89
	#else
sl@0
    90
	r = User::LoadLogicalDevice(_L("D_SHBUF_OWN.LDD"));
sl@0
    91
	if (r != KErrAlreadyExists)
sl@0
    92
		{
sl@0
    93
		test_KErrNone(r);
sl@0
    94
		}
sl@0
    95
	#endif
sl@0
    96
	}
sl@0
    97
sl@0
    98
void FreeDeviceDrivers()
sl@0
    99
	{
sl@0
   100
	TInt r = User::FreeLogicalDevice(KTestShBufClient);
sl@0
   101
	test_KErrNone(r);
sl@0
   102
	r = User::FreeLogicalDevice(KTestShBufOwn);
sl@0
   103
	test_KErrNone(r);
sl@0
   104
	}
sl@0
   105
sl@0
   106
void FillShBuf(RShBuf& aBuffer, TUint8 aValue)
sl@0
   107
	{
sl@0
   108
	TUint size = aBuffer.Size();
sl@0
   109
	TUint8* base = aBuffer.Ptr();
sl@0
   110
	test(size!=0);
sl@0
   111
	test(base!=0);
sl@0
   112
	memset(base,aValue,size);
sl@0
   113
	}
sl@0
   114
sl@0
   115
TBool CheckFillShBuf(RShBuf& aBuffer, TUint8 aValue)
sl@0
   116
	{
sl@0
   117
	TUint size = aBuffer.Size();
sl@0
   118
	TUint8* base = aBuffer.Ptr();
sl@0
   119
	test(size!=0);
sl@0
   120
	test(base!=0);
sl@0
   121
	TUint8* ptr = base;
sl@0
   122
	TUint8* end = ptr+size;
sl@0
   123
	while(ptr<end)
sl@0
   124
		{
sl@0
   125
		TUint8 b = *ptr++;
sl@0
   126
		if(b!=aValue)
sl@0
   127
			{
sl@0
   128
			RDebug::Printf("CheckFillShBuf failed at offset 0x%x, expected 0x%02x but got 0x%02x ",ptr-base-1,aValue,b);
sl@0
   129
			return EFalse;
sl@0
   130
			}
sl@0
   131
		}
sl@0
   132
	return ETrue;
sl@0
   133
	}
sl@0
   134
sl@0
   135
TBool CheckNotFillShBuf(RShBuf& aBuffer, TUint8 aValue)
sl@0
   136
	{
sl@0
   137
	TUint size = aBuffer.Size();
sl@0
   138
	TUint8* base = aBuffer.Ptr();
sl@0
   139
	test(size!=0);
sl@0
   140
	test(base!=0);
sl@0
   141
	TUint8* ptr = base;
sl@0
   142
	TUint8* end = ptr+size;
sl@0
   143
	while(ptr<end)
sl@0
   144
		{
sl@0
   145
		TUint8 b = *ptr++;
sl@0
   146
		if(b==aValue)
sl@0
   147
			{
sl@0
   148
			RDebug::Printf("CheckNotFillShBuf failed at offset 0x%x, expected not 0x%02x",ptr-base-1,aValue);
sl@0
   149
			return EFalse;
sl@0
   150
			}
sl@0
   151
		}
sl@0
   152
	return ETrue;
sl@0
   153
	}
sl@0
   154
sl@0
   155
/*
sl@0
   156
@SYMTestCaseID				1
sl@0
   157
@SYMTestCaseDesc			Create pool from user-side
sl@0
   158
@SYMREQ						REQ11423
sl@0
   159
@SYMTestActions
sl@0
   160
	1. Test Thread creates a pool (P1) and passes handle to device driver.
sl@0
   161
	2. Device driver opens pool and checks its attributes.
sl@0
   162
@SYMTestExpectedResults
sl@0
   163
	All OK.
sl@0
   164
@SYMTestPriority			Critical
sl@0
   165
*/
sl@0
   166
sl@0
   167
void CreateUserPool(TTestPoolType aPoolType)
sl@0
   168
	{
sl@0
   169
	test.Next(_L("Create user-side pool"));
sl@0
   170
	TInt r;
sl@0
   171
	TInt pagesize;
sl@0
   172
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
   173
	test_KErrNone(r);
sl@0
   174
sl@0
   175
	switch (aPoolType)
sl@0
   176
		{
sl@0
   177
		case ETestNonPageAligned:
sl@0
   178
		// Non-page-aligned pool
sl@0
   179
			{
sl@0
   180
			test.Printf(_L("Non-page-aligned\n"));
sl@0
   181
			test_Equal(0, P1.Handle());
sl@0
   182
			TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs, 8);
sl@0
   183
			r = P1.Create(inf,KDefaultPoolHandleFlags);
sl@0
   184
			test_KErrNone(r);
sl@0
   185
sl@0
   186
			r = P1.SetBufferWindow(-1, ETrue);
sl@0
   187
			test_Equal(KErrNotSupported, r);
sl@0
   188
sl@0
   189
			TShPoolInfo poolinfotokernel;
sl@0
   190
			poolinfotokernel.iBufSize = *PtrBufSize;
sl@0
   191
			poolinfotokernel.iInitialBufs = KTestPoolSizeInBufs;
sl@0
   192
			poolinfotokernel.iMaxBufs = KTestPoolSizeInBufs;
sl@0
   193
			poolinfotokernel.iGrowTriggerRatio = 0;
sl@0
   194
			poolinfotokernel.iGrowByRatio = 0;
sl@0
   195
			poolinfotokernel.iShrinkHysteresisRatio = 0;
sl@0
   196
			poolinfotokernel.iAlignment = 8;
sl@0
   197
			poolinfotokernel.iFlags = EShPoolNonPageAlignedBuffer;
sl@0
   198
			r = Ldd.OpenUserPool(P1.Handle(), poolinfotokernel);
sl@0
   199
			test_KErrNone(r);
sl@0
   200
sl@0
   201
			TShPoolInfo poolinfo;
sl@0
   202
			P1.GetInfo(poolinfo);
sl@0
   203
			test_Equal(*PtrBufSize, poolinfo.iBufSize);
sl@0
   204
			test_Equal(KTestPoolSizeInBufs, poolinfo.iInitialBufs);
sl@0
   205
			test_Equal(KTestPoolSizeInBufs, poolinfo.iMaxBufs);
sl@0
   206
			test_Equal(0, poolinfo.iGrowTriggerRatio);
sl@0
   207
			test_Equal(0, poolinfo.iGrowByRatio);
sl@0
   208
			test_Equal(0, poolinfo.iShrinkHysteresisRatio);
sl@0
   209
			test_Equal(8, poolinfo.iAlignment);
sl@0
   210
			test(poolinfo.iFlags & EShPoolNonPageAlignedBuffer);
sl@0
   211
			test(!(poolinfo.iFlags & EShPoolPageAlignedBuffer));
sl@0
   212
			break;
sl@0
   213
			}
sl@0
   214
		case ETestPageAligned:
sl@0
   215
		// Page-aligned pool
sl@0
   216
			{
sl@0
   217
			test.Printf(_L("Page-aligned\n"));
sl@0
   218
			test_Equal(0, P1.Handle());
sl@0
   219
sl@0
   220
			TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs);
sl@0
   221
			r = P1.Create(inf,KDefaultPoolHandleFlags);
sl@0
   222
			test_KErrNone(r);
sl@0
   223
sl@0
   224
			r = P1.SetBufferWindow(-1, ETrue);
sl@0
   225
			test_KErrNone(r);
sl@0
   226
sl@0
   227
			TShPoolInfo poolinfo;
sl@0
   228
			P1.GetInfo(poolinfo);
sl@0
   229
			test_Equal(*PtrBufSize, poolinfo.iBufSize);
sl@0
   230
			test_Equal(KTestPoolSizeInBufs, poolinfo.iInitialBufs);
sl@0
   231
			test_Equal(KTestPoolSizeInBufs, poolinfo.iMaxBufs);
sl@0
   232
			test_Equal(0, poolinfo.iGrowTriggerRatio);
sl@0
   233
			test_Equal(0, poolinfo.iGrowByRatio);
sl@0
   234
			test_Equal(0, poolinfo.iShrinkHysteresisRatio);
sl@0
   235
			test_Equal(Log2(pagesize), poolinfo.iAlignment);
sl@0
   236
			test(poolinfo.iFlags & EShPoolPageAlignedBuffer);
sl@0
   237
			test(!(poolinfo.iFlags & EShPoolNonPageAlignedBuffer));
sl@0
   238
sl@0
   239
			r = Ldd.OpenUserPool(P1.Handle(), poolinfo);
sl@0
   240
			test_KErrNone(r);
sl@0
   241
			break;
sl@0
   242
			}
sl@0
   243
		case ETestPageAlignedGrowing:
sl@0
   244
		// Page-aligned growing pool
sl@0
   245
			{
sl@0
   246
			test.Printf(_L("Page-aligned growing\n"));
sl@0
   247
			test_Equal(0, P1.Handle());
sl@0
   248
sl@0
   249
			TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs / 2);
sl@0
   250
			// Set shrink hysteresis high so pool can't shrink
sl@0
   251
			r = inf.SetSizingAttributes(KTestPoolSizeInBufs, 25, 26, 25600);
sl@0
   252
			test_KErrNone(r);
sl@0
   253
			r = P1.Create(inf,KDefaultPoolHandleFlags);
sl@0
   254
			test_KErrNone(r);
sl@0
   255
sl@0
   256
			r = P1.SetBufferWindow(-1, ETrue);
sl@0
   257
			test_KErrNone(r);
sl@0
   258
sl@0
   259
			TShPoolInfo poolinfo;
sl@0
   260
			P1.GetInfo(poolinfo);
sl@0
   261
			test_Equal(*PtrBufSize, poolinfo.iBufSize);
sl@0
   262
			test_Equal(KTestPoolSizeInBufs / 2, poolinfo.iInitialBufs);
sl@0
   263
			test_Equal(KTestPoolSizeInBufs, poolinfo.iMaxBufs);
sl@0
   264
			test_Equal(25, poolinfo.iGrowTriggerRatio);
sl@0
   265
			test_Equal(26, poolinfo.iGrowByRatio);
sl@0
   266
			test_Equal(25600, poolinfo.iShrinkHysteresisRatio);
sl@0
   267
			test_Equal(Log2(pagesize), poolinfo.iAlignment);
sl@0
   268
			test(poolinfo.iFlags & EShPoolPageAlignedBuffer);
sl@0
   269
			test(!(poolinfo.iFlags & EShPoolNonPageAlignedBuffer));
sl@0
   270
sl@0
   271
			r = Ldd.OpenUserPool(P1.Handle(), poolinfo);
sl@0
   272
			test_KErrNone(r);
sl@0
   273
			break;
sl@0
   274
			}
sl@0
   275
		default:
sl@0
   276
			test(EFalse);
sl@0
   277
		}
sl@0
   278
	}
sl@0
   279
sl@0
   280
/*
sl@0
   281
@SYMTestCaseID				2
sl@0
   282
@SYMTestCaseDesc			Create pool from kernel-side
sl@0
   283
@SYMREQ						REQ11423
sl@0
   284
@SYMTestActions
sl@0
   285
	1. Device Driver creates a pool (P2) and passes handle to this thread.
sl@0
   286
	2. Test Thread opens pool and checks its attributes.
sl@0
   287
@SYMTestExpectedResults
sl@0
   288
	1. Ok.
sl@0
   289
	2. Ok.
sl@0
   290
@SYMTestPriority			Critical
sl@0
   291
*/
sl@0
   292
sl@0
   293
void CreateKernelPool(TTestPoolType aPoolType)
sl@0
   294
	{
sl@0
   295
	test.Next(_L("Create kernel-side pool"));
sl@0
   296
	TInt r;
sl@0
   297
	TInt pagesize;
sl@0
   298
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
   299
	test_KErrNone(r);
sl@0
   300
	TInt handle;
sl@0
   301
sl@0
   302
	switch (aPoolType)
sl@0
   303
		{
sl@0
   304
		case ETestNonPageAligned:
sl@0
   305
		// Non-page-aligned pool
sl@0
   306
			{
sl@0
   307
			test.Printf(_L("Non-page-aligned\n"));
sl@0
   308
			test_Equal(0, P2.Handle());
sl@0
   309
sl@0
   310
			TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs, 8);
sl@0
   311
			r = Ldd.OpenKernelPool(inf, handle);
sl@0
   312
			test_KErrNone(r);
sl@0
   313
			P2.SetHandle(handle);
sl@0
   314
sl@0
   315
			TShPoolInfo poolinfo;
sl@0
   316
			P2.GetInfo(poolinfo);
sl@0
   317
			test_Equal(*PtrBufSize, poolinfo.iBufSize);
sl@0
   318
			test_Equal(KTestPoolSizeInBufs, poolinfo.iInitialBufs);
sl@0
   319
			test_Equal(KTestPoolSizeInBufs, poolinfo.iMaxBufs);
sl@0
   320
			test_Equal(0, poolinfo.iGrowTriggerRatio);
sl@0
   321
			test_Equal(0, poolinfo.iGrowByRatio);
sl@0
   322
			test_Equal(0, poolinfo.iShrinkHysteresisRatio);
sl@0
   323
			test_Equal(8, poolinfo.iAlignment);
sl@0
   324
			test(poolinfo.iFlags & EShPoolNonPageAlignedBuffer);
sl@0
   325
			test(!(poolinfo.iFlags & EShPoolPageAlignedBuffer));
sl@0
   326
			break;
sl@0
   327
			}
sl@0
   328
		case ETestPageAligned:
sl@0
   329
		// Page-aligned pool
sl@0
   330
			{
sl@0
   331
			test.Printf(_L("Page-aligned\n"));
sl@0
   332
			test_Equal(0, P2.Handle());
sl@0
   333
sl@0
   334
			TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs);
sl@0
   335
			r = Ldd.OpenKernelPool(inf, handle);
sl@0
   336
			test_KErrNone(r);
sl@0
   337
			P2.SetHandle(handle);
sl@0
   338
sl@0
   339
			r = P2.SetBufferWindow(-1, ETrue);
sl@0
   340
			test_KErrNone(r);
sl@0
   341
sl@0
   342
			TShPoolInfo poolinfo;
sl@0
   343
			P2.GetInfo(poolinfo);
sl@0
   344
			test_Equal(*PtrBufSize, poolinfo.iBufSize);
sl@0
   345
			test_Equal(KTestPoolSizeInBufs, poolinfo.iInitialBufs);
sl@0
   346
			test_Equal(KTestPoolSizeInBufs, poolinfo.iMaxBufs);
sl@0
   347
			test_Equal(0, poolinfo.iGrowTriggerRatio);
sl@0
   348
			test_Equal(0, poolinfo.iGrowByRatio);
sl@0
   349
			test_Equal(0, poolinfo.iShrinkHysteresisRatio);
sl@0
   350
			test_Equal(Log2(pagesize), poolinfo.iAlignment);
sl@0
   351
			test(poolinfo.iFlags & EShPoolPageAlignedBuffer);
sl@0
   352
			test(!(poolinfo.iFlags & EShPoolNonPageAlignedBuffer));
sl@0
   353
			break;
sl@0
   354
			}
sl@0
   355
		case ETestPageAlignedGrowing:
sl@0
   356
		// Page-aligned pool growing
sl@0
   357
			{
sl@0
   358
			test.Printf(_L("Page-aligned growing\n"));
sl@0
   359
			test_Equal(0, P2.Handle());
sl@0
   360
sl@0
   361
			TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs / 2);
sl@0
   362
			// Set shrink hysteresis high so pool can't shrink
sl@0
   363
			r = inf.SetSizingAttributes(KTestPoolSizeInBufs, 25, 26, 25600);
sl@0
   364
			test_KErrNone(r);
sl@0
   365
			r = Ldd.OpenKernelPool(inf, handle);
sl@0
   366
			test_KErrNone(r);
sl@0
   367
			P2.SetHandle(handle);
sl@0
   368
sl@0
   369
			r = P2.SetBufferWindow(-1, ETrue);
sl@0
   370
			test_KErrNone(r);
sl@0
   371
sl@0
   372
			TShPoolInfo poolinfo;
sl@0
   373
			P2.GetInfo(poolinfo);
sl@0
   374
			test_Equal(*PtrBufSize, poolinfo.iBufSize);
sl@0
   375
			test_Equal(KTestPoolSizeInBufs / 2, poolinfo.iInitialBufs);
sl@0
   376
			test_Equal(KTestPoolSizeInBufs, poolinfo.iMaxBufs);
sl@0
   377
			test_Equal(25, poolinfo.iGrowTriggerRatio);
sl@0
   378
			test_Equal(26, poolinfo.iGrowByRatio);
sl@0
   379
			test_Equal(25600, poolinfo.iShrinkHysteresisRatio);
sl@0
   380
			test_Equal(Log2(pagesize), poolinfo.iAlignment);
sl@0
   381
			test(poolinfo.iFlags & EShPoolPageAlignedBuffer);
sl@0
   382
			test(!(poolinfo.iFlags & EShPoolNonPageAlignedBuffer));
sl@0
   383
			break;
sl@0
   384
			}
sl@0
   385
		default:
sl@0
   386
			test(EFalse);
sl@0
   387
		}
sl@0
   388
	}
sl@0
   389
sl@0
   390
/*
sl@0
   391
@SYMTestCaseID				20
sl@0
   392
@SYMTestCaseDesc			Close pool from kernel-side
sl@0
   393
@SYMREQ						REQ11423
sl@0
   394
@SYMTestActions
sl@0
   395
	1. Device Driver closes P2.
sl@0
   396
	2. Test Thread closes P2.
sl@0
   397
@SYMTestExpectedResults
sl@0
   398
	1. OK and Access Count is now 1.
sl@0
   399
	2. OK
sl@0
   400
@SYMTestPriority			Critical
sl@0
   401
*/
sl@0
   402
sl@0
   403
void CloseKernelPool()
sl@0
   404
	{
sl@0
   405
	test.Next(_L("Close kernel-side pool"));
sl@0
   406
	TInt r;
sl@0
   407
sl@0
   408
	r = Ldd.CloseKernelPool();
sl@0
   409
	test_KErrNone(r);
sl@0
   410
sl@0
   411
	P2.Close();
sl@0
   412
sl@0
   413
	// wait for memory to be freed
sl@0
   414
	r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, (TAny*)5000, 0);
sl@0
   415
	test_KErrNone(r);
sl@0
   416
sl@0
   417
	}
sl@0
   418
sl@0
   419
/*
sl@0
   420
@SYMTestCaseID				21
sl@0
   421
@SYMTestCaseDesc			Close pool from user-side
sl@0
   422
@SYMREQ						REQ11423
sl@0
   423
@SYMTestActions
sl@0
   424
	1. Test Thread closes P1.
sl@0
   425
	2. Device Driver closes P1.
sl@0
   426
@SYMTestExpectedResults
sl@0
   427
	1. OK and Access Count is now 1.
sl@0
   428
	2. OK.
sl@0
   429
@SYMTestPriority			Critical
sl@0
   430
*/
sl@0
   431
sl@0
   432
void CloseUserPool()
sl@0
   433
	{
sl@0
   434
	test.Next(_L("Close user-side pool"));
sl@0
   435
	TInt r;
sl@0
   436
sl@0
   437
	P1.Close();
sl@0
   438
sl@0
   439
	r = Ldd.CloseUserPool();
sl@0
   440
	test_KErrNone(r);
sl@0
   441
sl@0
   442
	// wait for memory to be freed
sl@0
   443
	r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, (TAny*)5000, 0);
sl@0
   444
	test_KErrNone(r);
sl@0
   445
	}
sl@0
   446
sl@0
   447
/*
sl@0
   448
@SYMTestCaseID				3
sl@0
   449
@SYMTestCaseDesc			Buffer allocation from user-side
sl@0
   450
@SYMREQ						REQ11423
sl@0
   451
@SYMTestActions
sl@0
   452
	1. Test Thread creates a shared buffer on P1.
sl@0
   453
	2. Test Thread passes buffer to Device Driver.
sl@0
   454
	3. Device Driver obtains buffer and manipulates its contents.
sl@0
   455
	4. Device Driver releases buffer.
sl@0
   456
	5. Test Thread releases buffer.
sl@0
   457
@SYMTestExpectedResults
sl@0
   458
	1. Ok.
sl@0
   459
	2. Ok.
sl@0
   460
	3. Ok.
sl@0
   461
	4. Ok.
sl@0
   462
	5. Ok. Buffer de-allocated.
sl@0
   463
@SYMTestPriority			Critical
sl@0
   464
*/
sl@0
   465
sl@0
   466
void AllocateUserBuffer()
sl@0
   467
	{
sl@0
   468
	test.Next(_L("Allocate user-side buffer"));
sl@0
   469
	TInt r;
sl@0
   470
	RShBuf buf;
sl@0
   471
sl@0
   472
	// Allocate buffer on POOL 1
sl@0
   473
	__KHEAP_MARK;
sl@0
   474
	r = buf.Alloc(P1);
sl@0
   475
	test_KErrNone(r);
sl@0
   476
	__KHEAP_CHECK(0);
sl@0
   477
sl@0
   478
	TInt i;
sl@0
   479
	TShPoolInfo poolinfo1;
sl@0
   480
	P1.GetInfo(poolinfo1);
sl@0
   481
	TInt blocks = poolinfo1.iBufSize / KTestData1().Length();
sl@0
   482
sl@0
   483
	for (i = 0; i < blocks; i++)
sl@0
   484
		{
sl@0
   485
		TPtr8(buf.Ptr() + (i * KTestData1().Length()), KTestData1().Length(),KTestData1().Length()).Copy(KTestData1());
sl@0
   486
		}
sl@0
   487
	r = Ldd.ManipulateUserBuffer(buf.Handle());
sl@0
   488
sl@0
   489
	test_KErrNone(r);
sl@0
   490
sl@0
   491
	TBuf8<64> tmp;
sl@0
   492
sl@0
   493
	P1.GetInfo(poolinfo1);
sl@0
   494
	blocks = poolinfo1.iBufSize / tmp.MaxSize();
sl@0
   495
sl@0
   496
	for (i = 0 ; i < blocks; i++)
sl@0
   497
		{
sl@0
   498
		tmp.Fill(i);
sl@0
   499
		TPtrC8 ptrc(buf.Ptr() + (i * tmp.Length()), tmp.Length());
sl@0
   500
		r = tmp.Compare(ptrc);
sl@0
   501
		test_Equal(0, r);
sl@0
   502
		}
sl@0
   503
	buf.Close();
sl@0
   504
	__KHEAP_MARKEND;
sl@0
   505
sl@0
   506
	// Allocate buffer on POOL 2
sl@0
   507
	__KHEAP_MARK;
sl@0
   508
	r = buf.Alloc(P2);
sl@0
   509
	test_KErrNone(r);
sl@0
   510
	__KHEAP_CHECK(0);
sl@0
   511
sl@0
   512
	TShPoolInfo poolinfo2;
sl@0
   513
	P2.GetInfo(poolinfo2);
sl@0
   514
	blocks = poolinfo2.iBufSize / KTestData1().Length(); // PC REMOVE
sl@0
   515
sl@0
   516
	for (i = 0; i < blocks; i++)
sl@0
   517
		{
sl@0
   518
		TPtr8(buf.Ptr() + (i * KTestData1().Length()), KTestData1().Length(),KTestData1().Length()).Copy(KTestData1());
sl@0
   519
		}
sl@0
   520
sl@0
   521
	r = Ldd.ManipulateUserBuffer(buf.Handle());
sl@0
   522
	test_KErrNone(r);
sl@0
   523
sl@0
   524
	P2.GetInfo(poolinfo2);
sl@0
   525
	blocks = poolinfo2.iBufSize / tmp.MaxSize(); // PC REMOVE
sl@0
   526
sl@0
   527
	for (i = 0 ; i < blocks; i++)
sl@0
   528
		{
sl@0
   529
		tmp.Fill(i);
sl@0
   530
		r = tmp.Compare(TPtr8(buf.Ptr() + (i * tmp.Length()), tmp.Length(), tmp.Length()));
sl@0
   531
		test_Equal(0, r);
sl@0
   532
		}
sl@0
   533
	buf.Close();
sl@0
   534
	__KHEAP_MARKEND;
sl@0
   535
	}
sl@0
   536
sl@0
   537
/*
sl@0
   538
@SYMTestCaseID				4
sl@0
   539
@SYMTestCaseDesc			Buffer allocation from kernel-side
sl@0
   540
@SYMREQ						REQ11423
sl@0
   541
@SYMTestActions
sl@0
   542
	1. Device Driver creates a buffer on P2.
sl@0
   543
	2. Device Driver manipulates buffer and passes it to Test Thread.
sl@0
   544
	3. Test Thread manipulates buffer and send it back to Device Driver.
sl@0
   545
	4. Device Driver check buffer's contents and releases it.
sl@0
   546
@SYMTestExpectedResults
sl@0
   547
	1. Ok.
sl@0
   548
	2. Ok.
sl@0
   549
	3. Ok.
sl@0
   550
	4. Ok. Buffer de-allocated.
sl@0
   551
@SYMTestPriority			Critical
sl@0
   552
*/
sl@0
   553
sl@0
   554
void AllocateKernelBuffer()
sl@0
   555
	{
sl@0
   556
	test.Next(_L("Allocate kernel-side buffer"));
sl@0
   557
	TInt r;
sl@0
   558
	TInt handle;
sl@0
   559
	RShBuf kbuf0, kbuf1;
sl@0
   560
sl@0
   561
	// Allocate buffer on POOL 1
sl@0
   562
	r = Ldd.AllocateKernelBuffer(0, handle);
sl@0
   563
	test_KErrNone(r);
sl@0
   564
	kbuf0.SetHandle(handle);
sl@0
   565
sl@0
   566
	TInt i;
sl@0
   567
	TShPoolInfo poolinfo1;
sl@0
   568
	P1.GetInfo(poolinfo1);
sl@0
   569
	TInt blocks = poolinfo1.iBufSize / KTestData2().Length();
sl@0
   570
	for (i = 0; i < blocks; i++)
sl@0
   571
		{
sl@0
   572
		r = KTestData2().Compare(TPtr8(kbuf0.Ptr() + (i * KTestData2().Length()), KTestData2().Length(), KTestData2().Length()));
sl@0
   573
sl@0
   574
		test_Equal(0, r);
sl@0
   575
		}
sl@0
   576
	kbuf0.Close();
sl@0
   577
sl@0
   578
	// Allocate buffer on POOL 2
sl@0
   579
	r = Ldd.AllocateKernelBuffer(1, handle);
sl@0
   580
	test_KErrNone(r);
sl@0
   581
	kbuf1.SetHandle(handle);
sl@0
   582
sl@0
   583
	TShPoolInfo poolinfo2;
sl@0
   584
	P2.GetInfo(poolinfo2);
sl@0
   585
	blocks = poolinfo2.iBufSize / KTestData2().Length();
sl@0
   586
sl@0
   587
	for (i = 0; i < blocks; i++)
sl@0
   588
		{
sl@0
   589
		r = KTestData2().Compare(TPtr8(kbuf1.Ptr() + (i * KTestData2().Length()), KTestData2().Length(), KTestData2().Length()));
sl@0
   590
sl@0
   591
		test_Equal(0, r);
sl@0
   592
		}
sl@0
   593
	kbuf1.Close();
sl@0
   594
	}
sl@0
   595
sl@0
   596
sl@0
   597
/*
sl@0
   598
@SYMTestCaseID				X1
sl@0
   599
@SYMTestCaseDesc			Allocate maximum number of buffers in a pool (user/kernel)
sl@0
   600
@SYMREQ						REQ11423
sl@0
   601
@SYMTestActions
sl@0
   602
	Allocate as many buffers on a pool as possible.
sl@0
   603
	Free them all and re-allocate them again.
sl@0
   604
	Free them all.
sl@0
   605
@SYMTestExpectedResults
sl@0
   606
	Ok.
sl@0
   607
@SYMTestPriority			High
sl@0
   608
*/
sl@0
   609
sl@0
   610
void AllocateUserMax(RShPool& aPool)
sl@0
   611
	{
sl@0
   612
	test.Next(_L("Exhaust pool memory from user-side"));
sl@0
   613
	TInt r;
sl@0
   614
sl@0
   615
	TShPoolInfo poolinfo;
sl@0
   616
	aPool.GetInfo(poolinfo);
sl@0
   617
	TBool aligned = (poolinfo.iFlags & EShPoolPageAlignedBuffer);
sl@0
   618
	RDebug::Printf("aligned=%d",aligned);
sl@0
   619
sl@0
   620
	RArray<RShBuf> bufarray;
sl@0
   621
	do
sl@0
   622
		{
sl@0
   623
		RShBuf buf;
sl@0
   624
		r = buf.Alloc(aPool);
sl@0
   625
		if (r==KErrNoMemory && KTestPoolSizeInBufs>bufarray.Count())
sl@0
   626
			{
sl@0
   627
			// try again after a delay, to allow for background resource allocation
sl@0
   628
			
sl@0
   629
			User::After(1000000);
sl@0
   630
			r = buf.Alloc(aPool);
sl@0
   631
			}
sl@0
   632
		if (!r)
sl@0
   633
			{
sl@0
   634
			r = bufarray.Append(buf);
sl@0
   635
			test_KErrNone(r);
sl@0
   636
			FillShBuf(buf,0x99);
sl@0
   637
			}
sl@0
   638
		}
sl@0
   639
	while (r == KErrNone);
sl@0
   640
	test_Equal(KErrNoMemory, r);
sl@0
   641
	test_Compare(KTestPoolSizeInBufs, <=, bufarray.Count());
sl@0
   642
sl@0
   643
	TInt n = bufarray.Count();
sl@0
   644
	while (n)
sl@0
   645
		{
sl@0
   646
		bufarray[--n].Close();
sl@0
   647
		}
sl@0
   648
sl@0
   649
	User::After(500000);
sl@0
   650
sl@0
   651
	// Do it once more
sl@0
   652
	n = 0;
sl@0
   653
	while (n<bufarray.Count())
sl@0
   654
		{
sl@0
   655
		r = bufarray[n].Alloc(aPool);
sl@0
   656
		if (r==KErrNoMemory)
sl@0
   657
			{
sl@0
   658
			// try again after a delay, to allow for background resource allocation
sl@0
   659
			User::After(1000000);
sl@0
   660
			r = bufarray[n].Alloc(aPool);
sl@0
   661
			}
sl@0
   662
		test_Assert(r == KErrNone, test.Printf(_L("n=%d r=%d\n"), n, r));
sl@0
   663
		if(aligned)
sl@0
   664
			test(CheckNotFillShBuf(bufarray[n],0x99));
sl@0
   665
		++n;
sl@0
   666
		}
sl@0
   667
sl@0
   668
	RShBuf extrabuf;
sl@0
   669
	r = extrabuf.Alloc(aPool);
sl@0
   670
	test_Equal(KErrNoMemory, r);
sl@0
   671
sl@0
   672
	while (n)
sl@0
   673
		{
sl@0
   674
		bufarray[--n].Close();
sl@0
   675
		}
sl@0
   676
sl@0
   677
	bufarray.Close();
sl@0
   678
	}
sl@0
   679
sl@0
   680
void AllocateKernelMax()
sl@0
   681
	{
sl@0
   682
	test.Next(_L("Exhaust pool memory from kernel-side"));
sl@0
   683
	TInt r;
sl@0
   684
	TInt allocated;
sl@0
   685
	r = Ldd.AllocateMax(0, allocated); // P1
sl@0
   686
	test_KErrNone(r);
sl@0
   687
	test_Equal(KTestPoolSizeInBufs, allocated);
sl@0
   688
	r = Ldd.AllocateMax(1, allocated); // P2
sl@0
   689
	test_KErrNone(r);
sl@0
   690
	test_Equal(KTestPoolSizeInBufs, allocated);
sl@0
   691
	}
sl@0
   692
sl@0
   693
sl@0
   694
/*
sl@0
   695
@SYMTestCaseID				11
sl@0
   696
@SYMTestCaseDesc			Buffer alignment (kernel/user)
sl@0
   697
@SYMREQ						REQ11423
sl@0
   698
@SYMTestActions
sl@0
   699
	1. Test Thread creates several pools with different buffer alignment
sl@0
   700
	   requirements:
sl@0
   701
	2. Test Thread allocates buffers on all pools.
sl@0
   702
	3. Test Thread frees all buffers and close pools.
sl@0
   703
@SYMTestExpectedResults
sl@0
   704
	1. Ok.
sl@0
   705
	2. Buffers are aligned to the desired boundary.
sl@0
   706
	3. Ok.
sl@0
   707
@SYMTestPriority			High
sl@0
   708
*/
sl@0
   709
sl@0
   710
void BufferAlignmentUser()
sl@0
   711
	{
sl@0
   712
	test.Next(_L("Buffer alignment (User)"));
sl@0
   713
	TInt pagesize;
sl@0
   714
	TInt r;
sl@0
   715
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
   716
	test_KErrNone(r);
sl@0
   717
sl@0
   718
	// Non page aligned buffers
sl@0
   719
	TInt i;
sl@0
   720
	for (i = 0; i <= Log2(pagesize); i++)
sl@0
   721
		{
sl@0
   722
		test.Printf(_L("."));
sl@0
   723
		TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize, 20, i); // TODO: Change minbufs back to 8 when the pool growing code works
sl@0
   724
		RShPool pool;
sl@0
   725
		r = pool.Create(inf,KDefaultPoolHandleFlags);
sl@0
   726
		test_KErrNone(r);
sl@0
   727
sl@0
   728
		TInt j;
sl@0
   729
		RShBuf buf[20];
sl@0
   730
		for (j = 0; j < 20; j++)
sl@0
   731
			{
sl@0
   732
			r = buf[j].Alloc(pool);
sl@0
   733
			test_KErrNone(r);
sl@0
   734
			}
sl@0
   735
sl@0
   736
		TInt alignment = i;
sl@0
   737
		if (alignment < KTestMinimumAlignmentLog2)
sl@0
   738
			{
sl@0
   739
			alignment = KTestMinimumAlignmentLog2;
sl@0
   740
			}
sl@0
   741
		for (j = 0; j < 20; j++)
sl@0
   742
			{
sl@0
   743
			test_Assert(!((TUint32) buf[j].Ptr() & ((1 << alignment) - 1)),
sl@0
   744
				test.Printf(_L("Pool%d buf[%d].Base() == 0x%08x"), i, j, buf[j].Ptr()));
sl@0
   745
			}
sl@0
   746
sl@0
   747
		for (j = 0; j < 20; j++)
sl@0
   748
			{
sl@0
   749
			buf[j].Close();
sl@0
   750
			}
sl@0
   751
		pool.Close();
sl@0
   752
		// delay to allow the management dfc to run and close pool
sl@0
   753
		User::After(100000);
sl@0
   754
		}
sl@0
   755
	test.Printf(_L("\n"));
sl@0
   756
sl@0
   757
	// Page aligned buffers
sl@0
   758
	TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, 20); // TODO: Change minbufs back to 8 when the pool growing code works
sl@0
   759
	RShPool pool;
sl@0
   760
	r = pool.Create(inf,KDefaultPoolHandleFlags);
sl@0
   761
	test_KErrNone(r);
sl@0
   762
sl@0
   763
	r = pool.SetBufferWindow(-1, ETrue);
sl@0
   764
	test_KErrNone(r);
sl@0
   765
sl@0
   766
	TInt j;
sl@0
   767
	RShBuf buf[20];
sl@0
   768
	for (j = 0; j < 20; j++)
sl@0
   769
		{
sl@0
   770
		r = buf[j].Alloc(pool);
sl@0
   771
		test_KErrNone(r);
sl@0
   772
		}
sl@0
   773
sl@0
   774
	for (j = 0; j < 20; j++)
sl@0
   775
		{
sl@0
   776
		test_Assert(!((TUint32) buf[j].Ptr() & (pagesize - 1)),
sl@0
   777
					test.Printf(_L("buf[%d].Base() == 0x%08x"), j, buf[j].Ptr()));
sl@0
   778
		}
sl@0
   779
	for (j = 0; j < 20; j++)
sl@0
   780
		{
sl@0
   781
		buf[j].Close();
sl@0
   782
		}
sl@0
   783
	pool.Close();
sl@0
   784
	}
sl@0
   785
sl@0
   786
void BufferAlignmentKernel()
sl@0
   787
	{
sl@0
   788
	test.Next(_L("Buffer alignment (Kernel)"));
sl@0
   789
	TInt r;
sl@0
   790
sl@0
   791
	TInt pagesize;
sl@0
   792
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
   793
	test_KErrNone(r);
sl@0
   794
sl@0
   795
	for (TInt i = 0; i < Log2(pagesize); i++)
sl@0
   796
		{
sl@0
   797
		test.Printf(_L("."));
sl@0
   798
		r = Ldd.BufferAlignmentKernel(*PtrBufSize, i);
sl@0
   799
		test_KErrNone(r);
sl@0
   800
		// delay to allow the management dfc to run
sl@0
   801
		User::After(100000);
sl@0
   802
		}
sl@0
   803
	test.Printf(_L("\n"));
sl@0
   804
	}
sl@0
   805
sl@0
   806
/*
sl@0
   807
@SYMTestCaseID				6
sl@0
   808
@SYMTestCaseDesc			Create pool at specific physical address
sl@0
   809
@SYMREQ						REQ11423
sl@0
   810
@SYMTestActions
sl@0
   811
	1. Device Driver allocates memory chunk.
sl@0
   812
	2. Device Driver requests physical address of this memory chunk.
sl@0
   813
	3. Device Driver creates pool at physical address of the memory chunk.
sl@0
   814
	3. Device Driver allocate buffers on pool, free them and close pool.
sl@0
   815
@SYMTestExpectedResults
sl@0
   816
	1. Ok.
sl@0
   817
	2. Ok.
sl@0
   818
	3. Ok.
sl@0
   819
	4. Ok
sl@0
   820
@SYMTestPriority			High
sl@0
   821
*/
sl@0
   822
sl@0
   823
void CreateKernelPoolPhysAddr()
sl@0
   824
	{
sl@0
   825
	test.Next(_L("Create pool at specific physical address"));
sl@0
   826
	TInt r;
sl@0
   827
	test.Start(_L("Contiguous physical memory"));
sl@0
   828
	r = Ldd.CreatePoolPhysAddrCont(*PtrBufSize);
sl@0
   829
	test_KErrNone(r);
sl@0
   830
	test.Next(_L("Discontiguous physical memory"));
sl@0
   831
	r = Ldd.CreatePoolPhysAddrNonCont(*PtrBufSize);
sl@0
   832
	test_KErrNone(r);
sl@0
   833
	test.End();
sl@0
   834
	}
sl@0
   835
sl@0
   836
/*
sl@0
   837
@SYMTestCaseID				14
sl@0
   838
@SYMTestCaseDesc			Buffer separation and overwrites
sl@0
   839
@SYMREQ						REQ11423
sl@0
   840
@SYMTestActions
sl@0
   841
	1. Test Thread creates two pools:
sl@0
   842
		- A pool with no guard pages.
sl@0
   843
		- A pool with guard pages.
sl@0
   844
	2. Allocate two buffers on each pool.
sl@0
   845
	3. Test Thread creates Secondary Thread.
sl@0
   846
	4. Secondary Thread starts reading contents of the first buffer and keep
sl@0
   847
	   reading beyond its limits (using a pointer, not a descriptor).
sl@0
   848
	5. Secondary Thread starts writing on the first buffer and keep writing beyond
sl@0
   849
	   its limits (using a pointer, not a descriptor).
sl@0
   850
	6. Free buffers and close pools.
sl@0
   851
@SYMTestExpectedResults
sl@0
   852
	1. Ok.
sl@0
   853
	2. Ok.
sl@0
   854
	3. Ok.
sl@0
   855
	4. Secondary Thread panics when it attempts to read the guard page, if there
sl@0
   856
	   is one. Otherwise, it moves on to the second buffer. (Secondary Thread will
sl@0
   857
	   have to be restarted).
sl@0
   858
	5. Secondary Thread panics when it attempts to write on the guard page if
sl@0
   859
	   there is one. Otherwise, it carries on writing on to the second buffer.
sl@0
   860
	6. Ok.
sl@0
   861
@SYMTestPriority			High
sl@0
   862
*/
sl@0
   863
sl@0
   864
TInt ThreadGuardPagesRead(TAny* aArg)
sl@0
   865
	{
sl@0
   866
	TUint8* ptr = (TUint8*) aArg;
sl@0
   867
	if (ptr == NULL)
sl@0
   868
		{
sl@0
   869
		return KErrArgument;
sl@0
   870
		}
sl@0
   871
	TInt bufsize = *PtrBufSize;
sl@0
   872
	TInt i;
sl@0
   873
	TUint8 val = '$';
sl@0
   874
	TBool isok = ETrue;
sl@0
   875
	for (i = 0; i < bufsize; i++)
sl@0
   876
		{
sl@0
   877
		if (*(ptr + i) != val)
sl@0
   878
			{
sl@0
   879
			isok = EFalse;
sl@0
   880
			}
sl@0
   881
		}
sl@0
   882
	if (!isok)
sl@0
   883
		{
sl@0
   884
		return KErrUnknown;
sl@0
   885
		}
sl@0
   886
	return KErrNone;
sl@0
   887
	}
sl@0
   888
sl@0
   889
TInt ThreadGuardPagesWrite(TAny* aArg)
sl@0
   890
	{
sl@0
   891
	TUint8* ptr = (TUint8*) aArg;
sl@0
   892
	if (ptr == NULL)
sl@0
   893
		{
sl@0
   894
		return KErrArgument;
sl@0
   895
		}
sl@0
   896
	TInt bufsize = *PtrBufSize;
sl@0
   897
	TInt i;
sl@0
   898
	for (i = 0; i < bufsize; i++)
sl@0
   899
		{
sl@0
   900
		*(ptr + i) = '#';
sl@0
   901
		}
sl@0
   902
	return KErrNone;
sl@0
   903
	}
sl@0
   904
sl@0
   905
void GuardPages()
sl@0
   906
	{
sl@0
   907
	test.Next(_L("Guard pages"));
sl@0
   908
	TInt pagesize;
sl@0
   909
	TInt r;
sl@0
   910
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
   911
	test_KErrNone(r);
sl@0
   912
sl@0
   913
	// Create pools
sl@0
   914
	RShPool pool1;
sl@0
   915
	RShPool pool2;
sl@0
   916
	TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs);
sl@0
   917
	r = pool1.Create(inf,KDefaultPoolHandleFlags);
sl@0
   918
	test_KErrNone(r);
sl@0
   919
sl@0
   920
	r = pool1.SetBufferWindow(-1, ETrue);
sl@0
   921
	test_KErrNone(r);
sl@0
   922
sl@0
   923
	r = inf.SetGuardPages();
sl@0
   924
	test_KErrNone(r);
sl@0
   925
	r = pool2.Create(inf,KDefaultPoolHandleFlags);
sl@0
   926
	test_KErrNone(r);
sl@0
   927
sl@0
   928
	r = pool2.SetBufferWindow(-1, ETrue);
sl@0
   929
	test_KErrNone(r);
sl@0
   930
sl@0
   931
	// Allocate buffers
sl@0
   932
	RShBuf bufs1[KTestPoolSizeInBufs];
sl@0
   933
	RShBuf bufs2[KTestPoolSizeInBufs];
sl@0
   934
	TInt i;
sl@0
   935
	for (i = 0; i < KTestPoolSizeInBufs; i++)
sl@0
   936
		{
sl@0
   937
		r = bufs1[i].Alloc(pool1);
sl@0
   938
		test_Assert(r == KErrNone, test.Printf(_L("Pool1: i=%d r=%d\n"), i, r));
sl@0
   939
		TPtr8 ptr(bufs1[i].Ptr(), bufs1[i].Size(),bufs1[i].Size());
sl@0
   940
		ptr.Fill('$');
sl@0
   941
		}
sl@0
   942
	for (i = 0; i < KTestPoolSizeInBufs; i++)
sl@0
   943
		{
sl@0
   944
		r = bufs2[i].Alloc(pool2);
sl@0
   945
		test_Assert(r == KErrNone, test.Printf(_L("Pool2: i=%d r=%d\n"), i, r));
sl@0
   946
		TPtr8 ptr(bufs2[i].Ptr(), bufs1[i].Size(),bufs1[i].Size());
sl@0
   947
		ptr.Fill('$');
sl@0
   948
		}
sl@0
   949
sl@0
   950
	_LIT(KTestThreadRead, "GuardPagesReadTS%dP%dB%d");
sl@0
   951
	for (i = 0; i < KTestPoolSizeInBufs - 1; i++)
sl@0
   952
		{
sl@0
   953
		TBuf<40> threadname;
sl@0
   954
		RThread thread;
sl@0
   955
		TRequestStatus rs;
sl@0
   956
sl@0
   957
		// 1. Simple read within buffer
sl@0
   958
		// Pool 1
sl@0
   959
		threadname.Format(KTestThreadRead, 1, 1, i);
sl@0
   960
		r = thread.Create(threadname, ThreadGuardPagesRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
   961
			(TAny*) bufs1[i].Ptr());
sl@0
   962
		test_KErrNone(r);
sl@0
   963
		thread.Logon(rs);
sl@0
   964
		thread.Resume();
sl@0
   965
		User::WaitForRequest(rs);
sl@0
   966
		test_KErrNone(rs.Int());
sl@0
   967
		test_Equal(EExitKill, thread.ExitType());
sl@0
   968
		test_KErrNone(thread.ExitReason());
sl@0
   969
		thread.Close();
sl@0
   970
		// Pool 2
sl@0
   971
		threadname.Format(KTestThreadRead, 1, 2, i);
sl@0
   972
		r = thread.Create(threadname, ThreadGuardPagesRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
   973
			(TAny*) bufs2[i].Ptr());
sl@0
   974
		test_KErrNone(r);
sl@0
   975
		thread.Logon(rs);
sl@0
   976
		thread.Resume();
sl@0
   977
		User::WaitForRequest(rs);
sl@0
   978
		test_KErrNone(rs.Int());
sl@0
   979
		test_Equal(EExitKill, thread.ExitType());
sl@0
   980
		test_KErrNone(thread.ExitReason());
sl@0
   981
		thread.Close();
sl@0
   982
sl@0
   983
		// 2. If the buffer size is not a multiple of the MMU page size, it should be
sl@0
   984
		// possible to read after the buffer end until the page boundary
sl@0
   985
		if (*PtrBufSize % pagesize)
sl@0
   986
			{
sl@0
   987
			// Pool 1
sl@0
   988
			threadname.Format(KTestThreadRead, 2, 1, i);
sl@0
   989
			r = thread.Create(threadname, ThreadGuardPagesRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
   990
				(TAny*) (bufs1[i].Ptr() + pagesize - *PtrBufSize % pagesize));
sl@0
   991
			test_KErrNone(r);
sl@0
   992
			thread.Logon(rs);
sl@0
   993
			thread.Resume();
sl@0
   994
			User::WaitForRequest(rs);
sl@0
   995
			if (rs.Int() != KErrNone)
sl@0
   996
				{
sl@0
   997
				test_Equal(KErrUnknown, rs.Int());
sl@0
   998
				test_Equal(KErrUnknown, thread.ExitReason());
sl@0
   999
				}
sl@0
  1000
			test_Equal(EExitKill, thread.ExitType());
sl@0
  1001
			thread.Close();
sl@0
  1002
			// Pool 2
sl@0
  1003
			threadname.Format(KTestThreadRead, 2, 2, i);
sl@0
  1004
			r = thread.Create(threadname, ThreadGuardPagesRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1005
				(TAny*) (bufs2[i].Ptr() + pagesize - *PtrBufSize % pagesize));
sl@0
  1006
			test_KErrNone(r);
sl@0
  1007
			thread.Logon(rs);
sl@0
  1008
			thread.Resume();
sl@0
  1009
			User::WaitForRequest(rs);
sl@0
  1010
			if (rs.Int() != KErrNone)
sl@0
  1011
				{
sl@0
  1012
				test_Equal(KErrUnknown, rs.Int());
sl@0
  1013
				test_Equal(KErrUnknown, thread.ExitReason());
sl@0
  1014
				}
sl@0
  1015
			test_Equal(EExitKill, thread.ExitType());
sl@0
  1016
			thread.Close();
sl@0
  1017
			}
sl@0
  1018
sl@0
  1019
		// 3. Now we attempt to read the first byte on the next page after the end of
sl@0
  1020
		// our buffer.
sl@0
  1021
		TInt offset;
sl@0
  1022
		if (*PtrBufSize % pagesize)
sl@0
  1023
			{
sl@0
  1024
			offset = pagesize - *PtrBufSize % pagesize + 1;
sl@0
  1025
			}
sl@0
  1026
		else
sl@0
  1027
			{
sl@0
  1028
			offset = 1;
sl@0
  1029
			}
sl@0
  1030
		// Pool 1
sl@0
  1031
		if (bufs1[i + 1].Ptr() == bufs1[i].Ptr() + RoundUp(*PtrBufSize, Log2(pagesize)))
sl@0
  1032
			{
sl@0
  1033
			// Only perform this test if the next buffer comes immediately next to this
sl@0
  1034
			// one. This is not necessarily the case on the Flexible Memory Model.
sl@0
  1035
			threadname.Format(KTestThreadRead, 3, 1, i);
sl@0
  1036
			r = thread.Create(threadname, ThreadGuardPagesRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1037
				(TAny*) (bufs1[i].Ptr() + offset));
sl@0
  1038
			test_KErrNone(r);
sl@0
  1039
			thread.Logon(rs);
sl@0
  1040
			thread.Resume();
sl@0
  1041
			User::WaitForRequest(rs);
sl@0
  1042
			if (rs.Int() != KErrNone) // No guard page, so it should be fine
sl@0
  1043
				{
sl@0
  1044
				test_Equal(KErrUnknown, rs.Int());
sl@0
  1045
				test_Equal(KErrUnknown, thread.ExitReason());
sl@0
  1046
				}
sl@0
  1047
			test_Equal(EExitKill, thread.ExitType());
sl@0
  1048
			thread.Close();
sl@0
  1049
			}
sl@0
  1050
		// Pool 2
sl@0
  1051
		TBool jit = User::JustInTime();
sl@0
  1052
		User::SetJustInTime(EFalse);
sl@0
  1053
		threadname.Format(KTestThreadRead, 3, 2, i);
sl@0
  1054
		r = thread.Create(threadname, ThreadGuardPagesRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1055
			(TAny*) (bufs2[i].Ptr() + offset));
sl@0
  1056
		test_KErrNone(r);
sl@0
  1057
		thread.Logon(rs);
sl@0
  1058
		thread.Resume();
sl@0
  1059
		User::WaitForRequest(rs);
sl@0
  1060
		test_Equal(3, rs.Int());
sl@0
  1061
		test_Equal(EExitPanic, thread.ExitType());
sl@0
  1062
		test_Equal(3, thread.ExitReason()); // KERN-EXEC 3
sl@0
  1063
		thread.Close();
sl@0
  1064
		User::SetJustInTime(jit);
sl@0
  1065
		}
sl@0
  1066
sl@0
  1067
	_LIT(KTestThreadWrite, "GuardPagesWriteTS%dP%dB%d");
sl@0
  1068
	for (i = 0; i < KTestPoolSizeInBufs - 1; i++)
sl@0
  1069
		{
sl@0
  1070
		TBuf<40> threadname;
sl@0
  1071
		RThread thread;
sl@0
  1072
		TRequestStatus rs;
sl@0
  1073
sl@0
  1074
		// 1. Simple write within buffer
sl@0
  1075
		// Pool 1
sl@0
  1076
		threadname.Format(KTestThreadWrite, 1, 1, i);
sl@0
  1077
		r = thread.Create(threadname, ThreadGuardPagesWrite, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1078
			(TAny*) bufs1[i].Ptr());
sl@0
  1079
		test_KErrNone(r);
sl@0
  1080
		thread.Logon(rs);
sl@0
  1081
		thread.Resume();
sl@0
  1082
		User::WaitForRequest(rs);
sl@0
  1083
		test_KErrNone(rs.Int());
sl@0
  1084
		test_Equal(EExitKill, thread.ExitType());
sl@0
  1085
		test_KErrNone(thread.ExitReason());
sl@0
  1086
		thread.Close();
sl@0
  1087
		// Pool 2
sl@0
  1088
		threadname.Format(KTestThreadWrite, 1, 2, i);
sl@0
  1089
		r = thread.Create(threadname, ThreadGuardPagesWrite, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1090
			(TAny*) bufs2[i].Ptr());
sl@0
  1091
		test_KErrNone(r);
sl@0
  1092
		thread.Logon(rs);
sl@0
  1093
		thread.Resume();
sl@0
  1094
		User::WaitForRequest(rs);
sl@0
  1095
		test_KErrNone(rs.Int());
sl@0
  1096
		test_Equal(EExitKill, thread.ExitType());
sl@0
  1097
		test_KErrNone(thread.ExitReason());
sl@0
  1098
		thread.Close();
sl@0
  1099
sl@0
  1100
		// 2. If the buffer size is not a multiple of the MMU page size, it should be
sl@0
  1101
		// possible to write after the buffer end until the page boundary
sl@0
  1102
		if (*PtrBufSize % pagesize)
sl@0
  1103
			{
sl@0
  1104
			// Pool 1
sl@0
  1105
			threadname.Format(KTestThreadWrite, 2, 1, i);
sl@0
  1106
			r = thread.Create(threadname, ThreadGuardPagesWrite, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1107
				(TAny*) (bufs1[i].Ptr() + pagesize - *PtrBufSize % pagesize));
sl@0
  1108
			test_KErrNone(r);
sl@0
  1109
			thread.Logon(rs);
sl@0
  1110
			thread.Resume();
sl@0
  1111
			User::WaitForRequest(rs);
sl@0
  1112
			test_KErrNone(rs.Int());
sl@0
  1113
			test_Equal(EExitKill, thread.ExitType());
sl@0
  1114
			test_KErrNone(thread.ExitReason());
sl@0
  1115
			thread.Close();
sl@0
  1116
			// Pool 2
sl@0
  1117
			threadname.Format(KTestThreadWrite, 2, 2, i);
sl@0
  1118
			r = thread.Create(threadname, ThreadGuardPagesWrite, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1119
				(TAny*) (bufs2[i].Ptr() + pagesize - *PtrBufSize % pagesize));
sl@0
  1120
			test_KErrNone(r);
sl@0
  1121
			thread.Logon(rs);
sl@0
  1122
			thread.Resume();
sl@0
  1123
			User::WaitForRequest(rs);
sl@0
  1124
			test_KErrNone(rs.Int());
sl@0
  1125
			test_Equal(EExitKill, thread.ExitType());
sl@0
  1126
			test_KErrNone(thread.ExitReason());
sl@0
  1127
			thread.Close();
sl@0
  1128
			}
sl@0
  1129
sl@0
  1130
		// 3. Now we attempt to write on the first byte on the next page after the
sl@0
  1131
		// end of our buffer.
sl@0
  1132
		TInt offset;
sl@0
  1133
		if (*PtrBufSize % pagesize)
sl@0
  1134
			{
sl@0
  1135
			offset = pagesize - *PtrBufSize % pagesize + 1;
sl@0
  1136
			}
sl@0
  1137
		else
sl@0
  1138
			{
sl@0
  1139
			offset = 1;
sl@0
  1140
			}
sl@0
  1141
		// Pool 1
sl@0
  1142
		if (bufs1[i + 1].Ptr() == bufs1[i].Ptr() + RoundUp(*PtrBufSize, Log2(pagesize)))
sl@0
  1143
			{
sl@0
  1144
			// Only perform this test if the next buffer comes immediately next to this
sl@0
  1145
			// one. This is not necessarily the case on the Flexible Memory Model.
sl@0
  1146
			threadname.Format(KTestThreadWrite, 3, 1, i);
sl@0
  1147
			r = thread.Create(threadname, ThreadGuardPagesWrite, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1148
				(TAny*) (bufs1[i].Ptr() + offset));
sl@0
  1149
			test_KErrNone(r);
sl@0
  1150
			thread.Logon(rs);
sl@0
  1151
			thread.Resume();
sl@0
  1152
			User::WaitForRequest(rs);
sl@0
  1153
			test_KErrNone(rs.Int());
sl@0
  1154
			test_Equal(EExitKill, thread.ExitType());
sl@0
  1155
			test_KErrNone(thread.ExitReason());
sl@0
  1156
			thread.Close();
sl@0
  1157
			}
sl@0
  1158
sl@0
  1159
		// Pool 2
sl@0
  1160
		TBool jit = User::JustInTime();
sl@0
  1161
		User::SetJustInTime(EFalse);
sl@0
  1162
		threadname.Format(KTestThreadWrite, 3, 2, i);
sl@0
  1163
		r = thread.Create(threadname, ThreadGuardPagesWrite, KDefaultStackSize, KMinHeapSize, KMinHeapSize,
sl@0
  1164
			(TAny*) (bufs2[i].Ptr() + offset));
sl@0
  1165
		test_KErrNone(r);
sl@0
  1166
		thread.Logon(rs);
sl@0
  1167
		thread.Resume();
sl@0
  1168
		User::WaitForRequest(rs);
sl@0
  1169
		test_Equal(3, rs.Int());
sl@0
  1170
		test_Equal(EExitPanic, thread.ExitType());
sl@0
  1171
		test_Equal(3, thread.ExitReason()); // KERN-EXEC 3
sl@0
  1172
		thread.Close();
sl@0
  1173
		User::SetJustInTime(jit);
sl@0
  1174
		}
sl@0
  1175
sl@0
  1176
	// Free buffers
sl@0
  1177
	for (i = 0; i < KTestPoolSizeInBufs; i++)
sl@0
  1178
		{
sl@0
  1179
		bufs1[i].Close();
sl@0
  1180
		bufs2[i].Close();
sl@0
  1181
		}
sl@0
  1182
	pool1.Close();
sl@0
  1183
	pool2.Close();
sl@0
  1184
	}
sl@0
  1185
sl@0
  1186
/*
sl@0
  1187
@SYMTestCaseID				12
sl@0
  1188
@SYMTestCaseDesc			Buffer mapping
sl@0
  1189
@SYMREQ						REQ11423
sl@0
  1190
@SYMTestActions
sl@0
  1191
	1. Test Thread allocates buffer on a mappable pool.
sl@0
  1192
	2. Test Thread spawns Slave Process.
sl@0
  1193
	3. Test Thread passes buffer handle to Slave Process.
sl@0
  1194
	4. Slave Process attempts to read buffer then write to buffer.
sl@0
  1195
	5. Slave Process maps buffer.
sl@0
  1196
	6. Slave Process attempts to read buffer then write to buffer.
sl@0
  1197
	7. Slave Process unmaps buffer.
sl@0
  1198
	8. Slave Process attempts to read buffer then write to buffer.
sl@0
  1199
	9. Test Thread kills Slave Process and frees buffer.
sl@0
  1200
@SYMTestExpectedResults
sl@0
  1201
	1. Ok.
sl@0
  1202
	2. Ok.
sl@0
  1203
	3. Ok.
sl@0
  1204
	4. Slave Process panics. (and will have to be restarted)
sl@0
  1205
	5. Ok.
sl@0
  1206
	6. Ok.
sl@0
  1207
	7. Ok.
sl@0
  1208
	8. Slave Process panics.
sl@0
  1209
	9. Ok.
sl@0
  1210
@SYMTestPriority			High
sl@0
  1211
*/
sl@0
  1212
sl@0
  1213
TInt ThreadBufferMappingRead(TAny* aArg)
sl@0
  1214
	{
sl@0
  1215
	if (!aArg)
sl@0
  1216
		{
sl@0
  1217
		return KErrArgument;
sl@0
  1218
		}
sl@0
  1219
	RShBuf* buf = (RShBuf*) aArg;
sl@0
  1220
	TUint x = 0;
sl@0
  1221
	TUint i;
sl@0
  1222
	volatile TUint8* ptr = buf->Ptr();
sl@0
  1223
sl@0
  1224
	for (i = 0; i < buf->Size(); i++)
sl@0
  1225
		{
sl@0
  1226
		x += *(ptr + i);
sl@0
  1227
		}
sl@0
  1228
	return KErrNone;
sl@0
  1229
	}
sl@0
  1230
sl@0
  1231
TInt ThreadBufferMappingWrite(TAny* aArg)
sl@0
  1232
	{
sl@0
  1233
	if (!aArg)
sl@0
  1234
		{
sl@0
  1235
		return KErrArgument;
sl@0
  1236
		}
sl@0
  1237
	RShBuf* buf = (RShBuf*) aArg;
sl@0
  1238
	TPtr8 ptr(buf->Ptr(), buf->Size(),buf->Size());
sl@0
  1239
	ptr.Fill('Q');
sl@0
  1240
	return KErrNone;
sl@0
  1241
	}
sl@0
  1242
sl@0
  1243
const TInt KTestBufferMappingPoolTypes = 8;
sl@0
  1244
const TInt KTestBufferMappingTypes = 8;
sl@0
  1245
sl@0
  1246
void BufferMapping()
sl@0
  1247
	{
sl@0
  1248
	test.Next(_L("Buffer Mapping"));
sl@0
  1249
#ifdef __WINS__
sl@0
  1250
	test.Printf(_L("Does not run on the emulator. Skipped\n"));
sl@0
  1251
#else
sl@0
  1252
	TInt r;
sl@0
  1253
	RShPool pool[KTestBufferMappingPoolTypes];
sl@0
  1254
	RShBuf buf[KTestBufferMappingTypes][KTestBufferMappingPoolTypes];
sl@0
  1255
	TUint poolflags[KTestBufferMappingPoolTypes];
sl@0
  1256
	TInt bufferwindow[KTestBufferMappingPoolTypes];
sl@0
  1257
	TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, KTestBufferMappingTypes);
sl@0
  1258
sl@0
  1259
	// POOL TYPES
sl@0
  1260
	// ------------------------------------------
sl@0
  1261
	// Pool no.	AutoMap	Writeable	BufWindow
sl@0
  1262
	// 0			0			0			-1
sl@0
  1263
	// 1			1			0			-1
sl@0
  1264
	// 2			0			0			0
sl@0
  1265
	// 3			1			0			0
sl@0
  1266
	// 4			0			1			-1
sl@0
  1267
	// 5			1			1			-1
sl@0
  1268
	// 6			0			1			0
sl@0
  1269
	// 7			1			1			0
sl@0
  1270
sl@0
  1271
	TInt i;
sl@0
  1272
	test.Printf(_L("Create pools:"));
sl@0
  1273
	for (i = 0; i < KTestBufferMappingPoolTypes; i++)
sl@0
  1274
		{
sl@0
  1275
		poolflags[i] = EShPoolAllocate;
sl@0
  1276
		bufferwindow[i] = 0;
sl@0
  1277
		if (i % 2)
sl@0
  1278
			{
sl@0
  1279
			poolflags[i] |= EShPoolAutoMapBuf;
sl@0
  1280
			}
sl@0
  1281
		if (i > 3)
sl@0
  1282
			{
sl@0
  1283
			poolflags[i] |= EShPoolWriteable;
sl@0
  1284
			}
sl@0
  1285
		if (i % 4 > 1)
sl@0
  1286
			{
sl@0
  1287
			bufferwindow[i] = -1;
sl@0
  1288
			}
sl@0
  1289
		r = pool[i].Create(inf, poolflags[i] & ~EShPoolAutoMapBuf);
sl@0
  1290
		test_KErrNone(r);
sl@0
  1291
		r = pool[i].SetBufferWindow(bufferwindow[i], poolflags[i] & EShPoolAutoMapBuf);
sl@0
  1292
		test_KErrNone(r);
sl@0
  1293
		test.Printf(_L("."));
sl@0
  1294
		}
sl@0
  1295
	test.Printf(_L("\n"));
sl@0
  1296
sl@0
  1297
	// BUFFER TYPES
sl@0
  1298
	// Buffer no.	Actions
sl@0
  1299
	// 0			Alloc unmapped.
sl@0
  1300
	// 1			Alloc unmapped then unmap again.
sl@0
  1301
	// 2			Default Alloc. Unmap if it is a AutoMap pool.
sl@0
  1302
	// 3			Alloc unmapped. Map Read-Only.
sl@0
  1303
	// 4			Default Alloc. Unmap if it is a R/W pool and re-map Read-Only.
sl@0
  1304
	// 5			Alloc unmapped. Map R/W
sl@0
  1305
	// 6			Default Alloc. Unmap and re-map.
sl@0
  1306
	// 7            Default Alloc R/W. Map again with Read-Only setting.
sl@0
  1307
	// Depending on the pool type, the actions above might not always be possible.
sl@0
  1308
sl@0
  1309
	// Buffer allocation
sl@0
  1310
	TInt j;
sl@0
  1311
	test.Printf(_L("Allocate buffers\n"));
sl@0
  1312
	for (j = 0; j < KTestBufferMappingPoolTypes; j++)
sl@0
  1313
		{
sl@0
  1314
		test.Printf(_L("\nPool %d:"), j);
sl@0
  1315
		for (i = 0; i < KTestBufferMappingTypes; i++)
sl@0
  1316
			{
sl@0
  1317
			switch (i % KTestBufferMappingTypes)
sl@0
  1318
				{
sl@0
  1319
				// Unmapped buffers
sl@0
  1320
				case 0:
sl@0
  1321
				case 1:
sl@0
  1322
					// This should always result in an unmapped buffer
sl@0
  1323
					r = buf[i][j].Alloc(pool[j], EShPoolAllocNoMap);
sl@0
  1324
					test_KErrNone(r);
sl@0
  1325
sl@0
  1326
					if((i % KTestBufferMappingTypes) == 1)
sl@0
  1327
						{
sl@0
  1328
						// Alloc unmapped then unmap again.
sl@0
  1329
						r = buf[i][j].UnMap();
sl@0
  1330
						test_Equal(KErrNotFound, r);
sl@0
  1331
						}
sl@0
  1332
					break;
sl@0
  1333
				case 2:
sl@0
  1334
					r = buf[i][j].Alloc(pool[j]);
sl@0
  1335
					if (poolflags[j] & EShPoolAutoMapBuf)
sl@0
  1336
						{
sl@0
  1337
						if (bufferwindow[j] == 0)
sl@0
  1338
							{
sl@0
  1339
							// Can't ask for a mapped buffer when buffer window is not set
sl@0
  1340
							test_Equal(KErrNoMemory, r);
sl@0
  1341
							}
sl@0
  1342
						else
sl@0
  1343
							{
sl@0
  1344
							// Alloc'd buffer was mapped - unmap it
sl@0
  1345
							test_KErrNone(r);
sl@0
  1346
							r = buf[i][j].UnMap();
sl@0
  1347
							test_KErrNone(r);
sl@0
  1348
							}
sl@0
  1349
						}
sl@0
  1350
					else
sl@0
  1351
						{
sl@0
  1352
						// Buffer not mapped
sl@0
  1353
						test_KErrNone(r);
sl@0
  1354
						}
sl@0
  1355
					break;
sl@0
  1356
sl@0
  1357
				// Read-Only buffers
sl@0
  1358
				case 3:
sl@0
  1359
					r = buf[i][j].Alloc(pool[j], EShPoolAllocNoMap);
sl@0
  1360
					test_KErrNone(r);
sl@0
  1361
					r = buf[i][j].Map(ETrue);
sl@0
  1362
					if (bufferwindow[j])
sl@0
  1363
						{
sl@0
  1364
						test_KErrNone(r);
sl@0
  1365
						}
sl@0
  1366
					else
sl@0
  1367
						{
sl@0
  1368
						test_Equal(KErrNoMemory, r);
sl@0
  1369
						}
sl@0
  1370
					break;
sl@0
  1371
				case 4:
sl@0
  1372
					r = buf[i][j].Alloc(pool[j]);
sl@0
  1373
					if (poolflags[j] & EShPoolAutoMapBuf)
sl@0
  1374
						{
sl@0
  1375
						if (bufferwindow[j] == 0)
sl@0
  1376
							{
sl@0
  1377
							// Can't ask for a mapped buffer when buffer window is not set
sl@0
  1378
							test_Equal(KErrNoMemory, r);
sl@0
  1379
							}
sl@0
  1380
						else if (poolflags[j] & EShPoolWriteable)
sl@0
  1381
							{
sl@0
  1382
							// Alloc'd buffer was mapped R/W - re-map it R/O
sl@0
  1383
							test_KErrNone(r);
sl@0
  1384
							r = buf[i][j].UnMap();
sl@0
  1385
							test_KErrNone(r);
sl@0
  1386
							r = buf[i][j].Map(ETrue);
sl@0
  1387
							test_KErrNone(r);
sl@0
  1388
							}
sl@0
  1389
						else
sl@0
  1390
							{
sl@0
  1391
							// Nothing to do
sl@0
  1392
							test_KErrNone(r);
sl@0
  1393
							}
sl@0
  1394
						}
sl@0
  1395
					else
sl@0
  1396
						{
sl@0
  1397
						// Buffer not mapped
sl@0
  1398
						test_KErrNone(r);
sl@0
  1399
						if (bufferwindow[j])
sl@0
  1400
							{
sl@0
  1401
							if (poolflags[j] & EShPoolWriteable)
sl@0
  1402
								{
sl@0
  1403
								// Explicitly map Read-Only
sl@0
  1404
								r = buf[i][j].Map(ETrue);
sl@0
  1405
								test_KErrNone(r);
sl@0
  1406
								}
sl@0
  1407
							else
sl@0
  1408
								{
sl@0
  1409
								// If Pool is RO, map default
sl@0
  1410
								r = buf[i][j].Map();
sl@0
  1411
								test_KErrNone(r);
sl@0
  1412
								}
sl@0
  1413
							}
sl@0
  1414
						else
sl@0
  1415
							{
sl@0
  1416
							// Can't map buffer
sl@0
  1417
							r = buf[i][j].Map(ETrue);
sl@0
  1418
							test_Equal(KErrNoMemory, r);
sl@0
  1419
							}
sl@0
  1420
						}
sl@0
  1421
					break;
sl@0
  1422
sl@0
  1423
				// Mapped for Read-Write
sl@0
  1424
				case 5:
sl@0
  1425
					r = buf[i][j].Alloc(pool[j], EShPoolAllocNoMap);
sl@0
  1426
					test_KErrNone(r);
sl@0
  1427
					r = buf[i][j].Map();
sl@0
  1428
					if (bufferwindow[j] == 0)
sl@0
  1429
						{
sl@0
  1430
						test_Equal(KErrNoMemory, r);
sl@0
  1431
						}
sl@0
  1432
					else if (!(poolflags[j] & EShPoolWriteable))
sl@0
  1433
						{
sl@0
  1434
						test_KErrNone(r);
sl@0
  1435
						}
sl@0
  1436
					else
sl@0
  1437
						{
sl@0
  1438
						test_KErrNone(r);
sl@0
  1439
						}
sl@0
  1440
					break;
sl@0
  1441
				case 6:
sl@0
  1442
				case 7:
sl@0
  1443
					r = buf[i][j].Alloc(pool[j]);
sl@0
  1444
					if (poolflags[j] & EShPoolAutoMapBuf)
sl@0
  1445
						{
sl@0
  1446
						if (bufferwindow[j] == 0)
sl@0
  1447
							{
sl@0
  1448
							// Can't ask for a mapped buffer when buffer window is not set
sl@0
  1449
							test_Equal(KErrNoMemory, r);
sl@0
  1450
							}
sl@0
  1451
						else if (poolflags[j] & EShPoolWriteable)
sl@0
  1452
							{
sl@0
  1453
							// Alloc'd buffer was mapped R/W
sl@0
  1454
							test_KErrNone(r);
sl@0
  1455
sl@0
  1456
                            if((i % KTestBufferMappingTypes) == 7)
sl@0
  1457
                                {
sl@0
  1458
                                // Mapped for Read-Write then remapped as Read-Only
sl@0
  1459
                                r = buf[i][j].Map(true);
sl@0
  1460
                                test_Equal(KErrAlreadyExists, r);
sl@0
  1461
                                }
sl@0
  1462
							}
sl@0
  1463
						}
sl@0
  1464
					else
sl@0
  1465
						{
sl@0
  1466
						// Buffer not mapped
sl@0
  1467
						test_KErrNone(r);
sl@0
  1468
						if (bufferwindow[j])
sl@0
  1469
							{
sl@0
  1470
							if (poolflags[j] & EShPoolWriteable)
sl@0
  1471
								{
sl@0
  1472
								// Default mapping
sl@0
  1473
								r = buf[i][j].Map();
sl@0
  1474
                                test_KErrNone(r);
sl@0
  1475
sl@0
  1476
                                if((i % KTestBufferMappingTypes) == 7)
sl@0
  1477
                                    {
sl@0
  1478
                                    // Mapped for Read-Write then remapped as Read-Only
sl@0
  1479
                                    r = buf[i][j].Map(true);
sl@0
  1480
                                    test_Equal(KErrAlreadyExists, r);
sl@0
  1481
                                    }
sl@0
  1482
								}
sl@0
  1483
							}
sl@0
  1484
						else
sl@0
  1485
							{
sl@0
  1486
							// Can't map buffer
sl@0
  1487
							r = buf[i][j].Map(ETrue);
sl@0
  1488
							test_Equal(KErrNoMemory, r);
sl@0
  1489
							}
sl@0
  1490
						}
sl@0
  1491
					break;
sl@0
  1492
sl@0
  1493
	            default: test(EFalse);
sl@0
  1494
				}
sl@0
  1495
			test.Printf(_L("."));
sl@0
  1496
			}
sl@0
  1497
		}
sl@0
  1498
	test.Printf(_L("\n"));
sl@0
  1499
sl@0
  1500
	// Read and write tests
sl@0
  1501
	_LIT(KTestThreadName, "BufferMappingBuf%d(Test%d)");
sl@0
  1502
	test.Printf(_L("Read & Write tests\n"));
sl@0
  1503
	for (j = 0; j < KTestBufferMappingPoolTypes; j++)
sl@0
  1504
		{
sl@0
  1505
		for (i = 0; i < KTestBufferMappingTypes; i++)
sl@0
  1506
			{
sl@0
  1507
			if (buf[i][j].Handle())
sl@0
  1508
				{
sl@0
  1509
				switch (i % KTestBufferMappingTypes)
sl@0
  1510
					{
sl@0
  1511
					case 1:
sl@0
  1512
					case 2:
sl@0
  1513
					// Buffer not mapped - Read should fail
sl@0
  1514
					if (buf[i][j].Ptr() == NULL)
sl@0
  1515
						{
sl@0
  1516
						RThread thread;
sl@0
  1517
						TRequestStatus threadrs;
sl@0
  1518
						TBuf<40> threadname;
sl@0
  1519
						threadname.Format(KTestThreadName, i, (i % KTestBufferMappingTypes) + 1);
sl@0
  1520
						r = thread.Create(threadname, ThreadBufferMappingRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize, (TAny*) &buf[i][j]);
sl@0
  1521
						test_KErrNone(r);
sl@0
  1522
						thread.Logon(threadrs);
sl@0
  1523
						thread.Resume();
sl@0
  1524
						User::WaitForRequest(threadrs);
sl@0
  1525
						test_Equal(3, threadrs.Int());
sl@0
  1526
						test_Equal(EExitPanic, thread.ExitType());
sl@0
  1527
						test_Equal(3, thread.ExitReason()); // KERN-EXEC 3
sl@0
  1528
						CLOSE_AND_WAIT(thread);
sl@0
  1529
						// Map buffer read-only for next test
sl@0
  1530
						r = buf[i][j].Map(ETrue);
sl@0
  1531
						if (bufferwindow[j])
sl@0
  1532
							{
sl@0
  1533
							test_KErrNone(r);
sl@0
  1534
							}
sl@0
  1535
						else
sl@0
  1536
							{
sl@0
  1537
							test_Equal(KErrNoMemory, r);
sl@0
  1538
							}
sl@0
  1539
						}
sl@0
  1540
					case 3:
sl@0
  1541
					case 4:
sl@0
  1542
					// Buffer mapped for R/O access - Read should not fail
sl@0
  1543
					if (bufferwindow[j] == 0)
sl@0
  1544
						{
sl@0
  1545
						break;
sl@0
  1546
						}
sl@0
  1547
					else
sl@0
  1548
						{
sl@0
  1549
						RThread thread;
sl@0
  1550
						TRequestStatus threadrs;
sl@0
  1551
						TBuf<40> threadname;
sl@0
  1552
						threadname.Format(KTestThreadName, i, (i % KTestBufferMappingTypes) + 1);
sl@0
  1553
						r = thread.Create(threadname, ThreadBufferMappingRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize, (TAny*) &buf[i][j]);
sl@0
  1554
						test_KErrNone(r);
sl@0
  1555
						thread.Logon(threadrs);
sl@0
  1556
						thread.Resume();
sl@0
  1557
						User::WaitForRequest(threadrs);
sl@0
  1558
						test_KErrNone(threadrs.Int());
sl@0
  1559
						test_Equal(EExitKill, thread.ExitType());
sl@0
  1560
						test_KErrNone(thread.ExitReason());
sl@0
  1561
						CLOSE_AND_WAIT(thread);
sl@0
  1562
						}
sl@0
  1563
					// Write should fail
sl@0
  1564
					if (buf[i][j].Ptr())
sl@0
  1565
						{
sl@0
  1566
						RThread thread;
sl@0
  1567
						TRequestStatus threadrs;
sl@0
  1568
						TBuf<40> threadname;
sl@0
  1569
						threadname.Format(KTestThreadName, i, (i % KTestBufferMappingTypes) + 2);
sl@0
  1570
						r = thread.Create(threadname, ThreadBufferMappingWrite, KDefaultStackSize, KMinHeapSize, KMinHeapSize,(TAny*) &buf[i][j]);
sl@0
  1571
						test_KErrNone(r);
sl@0
  1572
						thread.Logon(threadrs);
sl@0
  1573
						thread.Resume();
sl@0
  1574
						User::WaitForRequest(threadrs);
sl@0
  1575
						test_Equal(3, threadrs.Int());
sl@0
  1576
						test_Equal(EExitPanic, thread.ExitType());
sl@0
  1577
						test_Equal(3, thread.ExitReason()); // KERN-EXEC 3
sl@0
  1578
						CLOSE_AND_WAIT(thread);
sl@0
  1579
						// Map buffer read-write for next test
sl@0
  1580
						r = buf[i][j].UnMap();
sl@0
  1581
						if(r != KErrNotFound)
sl@0
  1582
						    {
sl@0
  1583
						    test_KErrNone(r);
sl@0
  1584
						    }
sl@0
  1585
						r = buf[i][j].Map();
sl@0
  1586
			   			test_KErrNone(r);
sl@0
  1587
						}
sl@0
  1588
					case 5:
sl@0
  1589
					case 6:
sl@0
  1590
						// Buffer mapped for R/W access - Write should not fail
sl@0
  1591
					if (bufferwindow[j] == 0  || !(poolflags[j] & EShPoolWriteable))
sl@0
  1592
						{
sl@0
  1593
						break;
sl@0
  1594
						}
sl@0
  1595
					else
sl@0
  1596
						{
sl@0
  1597
						RThread thread;
sl@0
  1598
						TRequestStatus threadrs;
sl@0
  1599
						TBuf<40> threadname;
sl@0
  1600
						threadname.Format(KTestThreadName, i, (i % KTestBufferMappingTypes) + 1);
sl@0
  1601
						r = thread.Create(threadname, ThreadBufferMappingWrite, KDefaultStackSize, KMinHeapSize, KMinHeapSize,(TAny*) &buf[i][j]);
sl@0
  1602
						test_KErrNone(r);
sl@0
  1603
						thread.Logon(threadrs);
sl@0
  1604
						thread.Resume();
sl@0
  1605
						User::WaitForRequest(threadrs);
sl@0
  1606
						test_KErrNone(threadrs.Int());
sl@0
  1607
						test_Equal(EExitKill, thread.ExitType());
sl@0
  1608
						test_KErrNone(thread.ExitReason());
sl@0
  1609
						CLOSE_AND_WAIT(thread);
sl@0
  1610
						// Unmap buffer for next test
sl@0
  1611
						r = buf[i][j].UnMap();
sl@0
  1612
						test_KErrNone(r);
sl@0
  1613
						}
sl@0
  1614
					// Buffer not mapped - Read should fail
sl@0
  1615
					if (buf[i][j].Ptr())
sl@0
  1616
						{
sl@0
  1617
						RThread thread;
sl@0
  1618
						TRequestStatus threadrs;
sl@0
  1619
						TBuf<40> threadname;
sl@0
  1620
						threadname.Format(KTestThreadName, i, (i % KTestBufferMappingTypes) + 2);
sl@0
  1621
						r = thread.Create(threadname, ThreadBufferMappingRead, KDefaultStackSize, KMinHeapSize, KMinHeapSize,(TAny*) &buf[i][j]);
sl@0
  1622
						test_KErrNone(r);
sl@0
  1623
						thread.Logon(threadrs);
sl@0
  1624
						thread.Resume();
sl@0
  1625
						User::WaitForRequest(threadrs);
sl@0
  1626
						test_Equal(3, threadrs.Int());
sl@0
  1627
						test_Equal(EExitPanic, thread.ExitType());
sl@0
  1628
						test_Equal(3, thread.ExitReason()); // KERN-EXEC 3
sl@0
  1629
						CLOSE_AND_WAIT(thread);
sl@0
  1630
						}
sl@0
  1631
					}
sl@0
  1632
				}
sl@0
  1633
			buf[i][j].Close();
sl@0
  1634
			test.Printf(_L("."));
sl@0
  1635
			}
sl@0
  1636
		pool[j].Close();
sl@0
  1637
		test.Printf(_L("\n"));
sl@0
  1638
		}
sl@0
  1639
#endif
sl@0
  1640
	}
sl@0
  1641
sl@0
  1642
void BufferWindow()
sl@0
  1643
	{
sl@0
  1644
	test.Next(_L("Buffer Window tests"));
sl@0
  1645
#ifdef __WINS__
sl@0
  1646
	test.Printf(_L("Does not run on the emulator. Skipped\n"));
sl@0
  1647
#else
sl@0
  1648
	TInt r;
sl@0
  1649
	RShPool pool;
sl@0
  1650
	RShBuf buf[KTestPoolSizeInBufs * 2 + 1];
sl@0
  1651
	TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs * 2);
sl@0
  1652
	r = pool.Create(inf, KDefaultPoolHandleFlags);
sl@0
  1653
	test_KErrNone(r);
sl@0
  1654
sl@0
  1655
	// Allocate buffer but don't map them to this process memory
sl@0
  1656
	TInt i;
sl@0
  1657
	for (i = 0; i < KTestPoolSizeInBufs * 2; i++)
sl@0
  1658
		{
sl@0
  1659
		r = buf[i].Alloc(pool, EShPoolAllocNoMap);
sl@0
  1660
		test_KErrNone(r);
sl@0
  1661
		}
sl@0
  1662
sl@0
  1663
	// Pool is full
sl@0
  1664
	r = buf[KTestPoolSizeInBufs * 2].Alloc(pool, EShPoolAllocNoMap);
sl@0
  1665
	test_Equal(KErrNoMemory, r);
sl@0
  1666
	r = buf[0].Map();
sl@0
  1667
	test_Equal(KErrNoMemory, r);
sl@0
  1668
sl@0
  1669
	// Open a one-buffer window
sl@0
  1670
	r = pool.SetBufferWindow(1, ETrue);
sl@0
  1671
	test_KErrNone(r);
sl@0
  1672
	r = buf[0].Map();
sl@0
  1673
	test_KErrNone(r);
sl@0
  1674
	TPtr8 ptr0(buf[0].Ptr(), buf[0].Size(),buf[0].Size());
sl@0
  1675
	ptr0.Fill('>');
sl@0
  1676
	r = buf[1].Map();
sl@0
  1677
	test_Equal(KErrNoMemory, r);
sl@0
  1678
	r = buf[0].UnMap();
sl@0
  1679
	test_KErrNone(r);
sl@0
  1680
	r = buf[1].Map();
sl@0
  1681
	test_KErrNone(r);
sl@0
  1682
	TPtr8 ptr1(buf[0].Ptr(), buf[0].Size(),buf[0].Size());
sl@0
  1683
	ptr1.Fill('<');
sl@0
  1684
	r = buf[2].Map();
sl@0
  1685
	test_Equal(KErrNoMemory, r);
sl@0
  1686
sl@0
  1687
	// Enlarge window by one buffer
sl@0
  1688
	r = pool.SetBufferWindow(2, ETrue);
sl@0
  1689
	test_Equal(KErrAlreadyExists, r);
sl@0
  1690
sl@0
  1691
	// Close All buffers
sl@0
  1692
	for (i = 0; i < KTestPoolSizeInBufs * 2; i++)
sl@0
  1693
		{
sl@0
  1694
		buf[i].Close();
sl@0
  1695
		}
sl@0
  1696
sl@0
  1697
	pool.Close();
sl@0
  1698
	r = pool.Create(inf, KDefaultPoolHandleFlags);
sl@0
  1699
	test_KErrNone(r);
sl@0
  1700
sl@0
  1701
	r = pool.SetBufferWindow(KTestPoolSizeInBufs, ETrue); // Half the pool size
sl@0
  1702
	test_KErrNone(r);
sl@0
  1703
	for (i = 0; i < KTestPoolSizeInBufs * 2 - 1; i++)
sl@0
  1704
		{
sl@0
  1705
		if (i < KTestPoolSizeInBufs)
sl@0
  1706
			{
sl@0
  1707
			r = buf[i].Alloc(pool, 0);
sl@0
  1708
			test_KErrNone(r);
sl@0
  1709
			TPtr8 ptr(buf[0].Ptr(), buf[0].Size(),buf[0].Size());
sl@0
  1710
			ptr.Fill('?');
sl@0
  1711
			}
sl@0
  1712
		else
sl@0
  1713
			{
sl@0
  1714
			r = buf[i].Alloc(pool, EShPoolAllocNoMap);
sl@0
  1715
			test_KErrNone(r);
sl@0
  1716
			}
sl@0
  1717
		}
sl@0
  1718
	r = buf[KTestPoolSizeInBufs * 2].Alloc(pool, 0);
sl@0
  1719
	test_Equal(KErrNoMemory, r);
sl@0
  1720
	r = buf[KTestPoolSizeInBufs].Map();
sl@0
  1721
	test_Equal(KErrNoMemory, r);
sl@0
  1722
	r = buf[KTestPoolSizeInBufs * 2].Alloc(pool, EShPoolAllocNoMap);
sl@0
  1723
	test_KErrNone(r);
sl@0
  1724
sl@0
  1725
	// That's it
sl@0
  1726
	for (i = 0; i < (KTestPoolSizeInBufs * 2)  + 1; i++)
sl@0
  1727
		{
sl@0
  1728
		buf[i].Close();
sl@0
  1729
		}
sl@0
  1730
	pool.Close();
sl@0
  1731
sl@0
  1732
	// Try again with automap set to false
sl@0
  1733
	RShPool pool2;
sl@0
  1734
	r = pool2.Create(inf, KDefaultPoolHandleFlags);
sl@0
  1735
	test_KErrNone(r);
sl@0
  1736
	for (i = 0; i < KTestPoolSizeInBufs * 2; i++)
sl@0
  1737
		{
sl@0
  1738
		r = buf[i].Alloc(pool2, 0);
sl@0
  1739
		test_KErrNone(r);
sl@0
  1740
		}
sl@0
  1741
	r = pool2.SetBufferWindow(-1, EFalse);
sl@0
  1742
	test_KErrNone(r);
sl@0
  1743
	for (i = 0; i < KTestPoolSizeInBufs * 2; i++)
sl@0
  1744
		{
sl@0
  1745
		r = buf[i].Map(ETrue);
sl@0
  1746
		test_KErrNone(r);
sl@0
  1747
		}
sl@0
  1748
	for (i = 0; i < KTestPoolSizeInBufs * 2; i++)
sl@0
  1749
		{
sl@0
  1750
		buf[i].Close();
sl@0
  1751
		}
sl@0
  1752
	pool2.Close();
sl@0
  1753
#endif
sl@0
  1754
	}
sl@0
  1755
sl@0
  1756
/*
sl@0
  1757
@SYMTestCaseID				7
sl@0
  1758
@SYMTestCaseDesc			Trigger notifications
sl@0
  1759
@SYMREQ						REQ11423
sl@0
  1760
@SYMTestActions
sl@0
  1761
	Set Low Space Notifications on various thresholds.
sl@0
  1762
	In a separate thread, keep allocating buffers.
sl@0
  1763
@SYMTestExpectedResults
sl@0
  1764
	Notifications are completed when their respective levels are reached.
sl@0
  1765
@SYMTestPriority			Medium
sl@0
  1766
*/
sl@0
  1767
sl@0
  1768
TInt ThreadNotifications(TAny* aArg)
sl@0
  1769
	{
sl@0
  1770
	if (!aArg)
sl@0
  1771
		{
sl@0
  1772
		return KErrArgument;
sl@0
  1773
		}
sl@0
  1774
	RShPool* pool = (RShPool*) aArg;
sl@0
  1775
	RArray<RShBuf> bufarray;
sl@0
  1776
	TInt r;
sl@0
  1777
	RSemaphore sem;
sl@0
  1778
	r = sem.OpenGlobal(KTestLowSpaceSemaphore);
sl@0
  1779
	if (r)
sl@0
  1780
		{
sl@0
  1781
		RDebug::Printf("Line %d: r=%d", __LINE__, r);
sl@0
  1782
		return r;
sl@0
  1783
		}
sl@0
  1784
	// Start allocating buffers
sl@0
  1785
	while (pool->FreeCount() > 1)
sl@0
  1786
		{
sl@0
  1787
		RShBuf buf;
sl@0
  1788
		r = buf.Alloc(*pool);
sl@0
  1789
		if (r)
sl@0
  1790
			{
sl@0
  1791
			RDebug::Printf("Line %d: count=%d r=%d", __LINE__, bufarray.Count(), r);
sl@0
  1792
			return r;
sl@0
  1793
			}
sl@0
  1794
		bufarray.Append(buf);
sl@0
  1795
		if ((bufarray.Count() == 1)								// wait for low3
sl@0
  1796
			|| (bufarray.Count() == KTestPoolSizeInBufs - 2)	// wait for low2
sl@0
  1797
			|| (bufarray.Count() == KTestPoolSizeInBufs - 1))	// wait for low1/low4
sl@0
  1798
				{
sl@0
  1799
				r = sem.Wait(5000000); // 5 second timeout
sl@0
  1800
				if (r)
sl@0
  1801
					{
sl@0
  1802
					RDebug::Printf("Line %d: count=%d r=%d", __LINE__, bufarray.Count(), r);
sl@0
  1803
					return r;
sl@0
  1804
					}
sl@0
  1805
				}
sl@0
  1806
		}
sl@0
  1807
sl@0
  1808
	// Free all buffers
sl@0
  1809
	while (bufarray.Count())
sl@0
  1810
		{
sl@0
  1811
		bufarray[0].Close();
sl@0
  1812
		bufarray.Remove(0);
sl@0
  1813
		if ((bufarray.Count() == KTestPoolSizeInBufs - 2)		// wait for free3
sl@0
  1814
			|| (bufarray.Count() == 1)							// wait for free2
sl@0
  1815
			|| (bufarray.Count() == 0))							// wait for free1/free4
sl@0
  1816
				{
sl@0
  1817
				r = sem.Wait(5000000); // 5 second timeout
sl@0
  1818
				if (r)
sl@0
  1819
					{
sl@0
  1820
					RDebug::Printf("Line %d: count=%d r=%d", __LINE__, bufarray.Count(), r);
sl@0
  1821
					return r;
sl@0
  1822
					}
sl@0
  1823
				}
sl@0
  1824
		}
sl@0
  1825
	bufarray.Close();
sl@0
  1826
	sem.Close();
sl@0
  1827
	return KErrNone;
sl@0
  1828
	}
sl@0
  1829
sl@0
  1830
enum TTestLowSpaceType
sl@0
  1831
	{
sl@0
  1832
	ETestCancelNonExistent,
sl@0
  1833
	ETestCancelTwice
sl@0
  1834
	};
sl@0
  1835
sl@0
  1836
struct TTestThreadLowSpacePanicArgs
sl@0
  1837
	{
sl@0
  1838
	RShPool*			iPool;
sl@0
  1839
	TUint				iThreshold1;
sl@0
  1840
	TUint				iThreshold2;
sl@0
  1841
	TTestLowSpaceType	iType;
sl@0
  1842
	};
sl@0
  1843
sl@0
  1844
TInt ThreadLowSpacePanic(TAny* aArg)
sl@0
  1845
	{
sl@0
  1846
	if (!aArg)
sl@0
  1847
		{
sl@0
  1848
		return KErrArgument;
sl@0
  1849
		}
sl@0
  1850
	TTestThreadLowSpacePanicArgs& targs = *(TTestThreadLowSpacePanicArgs*) aArg;
sl@0
  1851
	TRequestStatus rs;
sl@0
  1852
	if (targs.iType == ETestCancelNonExistent)
sl@0
  1853
		{
sl@0
  1854
		targs.iPool->CancelLowSpaceNotification(rs); // should panic
sl@0
  1855
		}
sl@0
  1856
	else if (targs.iType == ETestCancelTwice)
sl@0
  1857
		{
sl@0
  1858
		targs.iPool->RequestLowSpaceNotification(targs.iThreshold1, rs);
sl@0
  1859
		targs.iPool->CancelLowSpaceNotification(rs);
sl@0
  1860
		targs.iPool->CancelLowSpaceNotification(rs); // should panic
sl@0
  1861
		}
sl@0
  1862
	else
sl@0
  1863
		{
sl@0
  1864
		return KErrArgument;
sl@0
  1865
		}
sl@0
  1866
	return KErrNone;
sl@0
  1867
	}
sl@0
  1868
sl@0
  1869
/*
sl@0
  1870
 * CancelLowSpaceNotification() no longer panic()s if it can't find the
sl@0
  1871
 * notification, so this routine not currently called.
sl@0
  1872
 */
sl@0
  1873
void RequestLowSpacePanic(RShPool& aPool, TUint aThreshold1, TUint aThreshold2, TTestLowSpaceType aType, TInt aLine)
sl@0
  1874
	{
sl@0
  1875
	static TInt count = 0;
sl@0
  1876
	count++;
sl@0
  1877
	test.Printf(_L("RequestLowSpacePanic@%d(%d)\n"), aLine, count);
sl@0
  1878
	TBool jit = User::JustInTime();
sl@0
  1879
	User::SetJustInTime(EFalse);
sl@0
  1880
	TInt expectedpaniccode = KErrNone;	// Initialised to silence compiler warnings
sl@0
  1881
	switch (aType)
sl@0
  1882
		{
sl@0
  1883
		case ETestCancelNonExistent:
sl@0
  1884
		case ETestCancelTwice:
sl@0
  1885
			expectedpaniccode = KErrNotFound;
sl@0
  1886
			break;
sl@0
  1887
		default:
sl@0
  1888
			test(EFalse);
sl@0
  1889
		}
sl@0
  1890
	//
sl@0
  1891
	TTestThreadLowSpacePanicArgs targs;
sl@0
  1892
	targs.iPool = &aPool;
sl@0
  1893
	targs.iThreshold1 = aThreshold1;
sl@0
  1894
	targs.iThreshold2 = aThreshold2;
sl@0
  1895
	targs.iType = aType;
sl@0
  1896
	//
sl@0
  1897
	RThread threadpanic;
sl@0
  1898
	TRequestStatus threadpanicrs;
sl@0
  1899
	TInt r;
sl@0
  1900
	TBuf<30> threadname;
sl@0
  1901
	threadname.Format(_L("ThreadLowSpacePanic%d"), count);
sl@0
  1902
	r = threadpanic.Create(threadname, ThreadLowSpacePanic, KDefaultStackSize, KMinHeapSize, 1 << 20, (TAny*) &targs);
sl@0
  1903
	test_KErrNone(r);
sl@0
  1904
	threadpanic.Logon(threadpanicrs);
sl@0
  1905
	threadpanic.Resume();
sl@0
  1906
	User::WaitForRequest(threadpanicrs);
sl@0
  1907
	//
sl@0
  1908
	test_Equal(expectedpaniccode, threadpanicrs.Int());
sl@0
  1909
	test_Equal(EExitPanic, threadpanic.ExitType());
sl@0
  1910
	test_Equal(expectedpaniccode, threadpanic.ExitReason());
sl@0
  1911
	threadpanic.Close();
sl@0
  1912
	User::SetJustInTime(jit);
sl@0
  1913
	}
sl@0
  1914
sl@0
  1915
void NotificationRequests(RShPool& aPool)
sl@0
  1916
	{
sl@0
  1917
	test.Next(_L("Notifications"));
sl@0
  1918
	TInt r;
sl@0
  1919
sl@0
  1920
	RSemaphore sem;
sl@0
  1921
	r = sem.CreateGlobal(KTestLowSpaceSemaphore, 0);
sl@0
  1922
	test_KErrNone(r);
sl@0
  1923
	RTimer timer;
sl@0
  1924
	r = timer.CreateLocal();
sl@0
  1925
	test_KErrNone(r);
sl@0
  1926
	RThread thread;
sl@0
  1927
	TRequestStatus threadrs;
sl@0
  1928
	r = thread.Create(_L("ThreadNotifications"), ThreadNotifications, KDefaultStackSize, KMinHeapSize, 1 << 20, (TAny*) &aPool);
sl@0
  1929
	test_KErrNone(r);
sl@0
  1930
	thread.SetPriority(EPriorityMore);
sl@0
  1931
	thread.Logon(threadrs);
sl@0
  1932
sl@0
  1933
	test.Printf(_L("Low space notification\n"));
sl@0
  1934
	TRequestStatus low1;
sl@0
  1935
	TRequestStatus low2;
sl@0
  1936
	TRequestStatus low3;
sl@0
  1937
	TRequestStatus low4;
sl@0
  1938
	TRequestStatus low5;
sl@0
  1939
	TRequestStatus low6;
sl@0
  1940
	aPool.RequestLowSpaceNotification(1, low1);
sl@0
  1941
	test_Equal(KRequestPending, low1.Int());
sl@0
  1942
	aPool.RequestLowSpaceNotification(2, low2);
sl@0
  1943
	test_Equal(KRequestPending, low2.Int());
sl@0
  1944
	aPool.RequestLowSpaceNotification(aPool.FreeCount() - 1, low3);
sl@0
  1945
	test_Equal(KRequestPending, low3.Int());
sl@0
  1946
	aPool.RequestLowSpaceNotification(1, low4);
sl@0
  1947
	test_Equal(KRequestPending, low4.Int());
sl@0
  1948
	aPool.RequestLowSpaceNotification(0, low5); // Never completes
sl@0
  1949
	test_Equal(KRequestPending, low5.Int());
sl@0
  1950
	aPool.RequestLowSpaceNotification(KMaxTUint, low6); // Completes instantly
sl@0
  1951
	TRequestStatus timeoutlow;
sl@0
  1952
	timer.After(timeoutlow, 5000000); // 5 seconds time out
sl@0
  1953
	User::WaitForRequest(low6, timeoutlow);
sl@0
  1954
	test_KErrNone(low6.Int());
sl@0
  1955
	test_Equal(KRequestPending, low1.Int());
sl@0
  1956
	test_Equal(KRequestPending, low2.Int());
sl@0
  1957
	test_Equal(KRequestPending, low3.Int());
sl@0
  1958
	test_Equal(KRequestPending, low4.Int());
sl@0
  1959
	test_Equal(KRequestPending, low5.Int());
sl@0
  1960
	timer.Cancel();
sl@0
  1961
	User::WaitForRequest(timeoutlow);
sl@0
  1962
	thread.Resume();
sl@0
  1963
	User::WaitForRequest(low3, threadrs);
sl@0
  1964
	test_KErrNone(low3.Int());
sl@0
  1965
	test_Equal(KRequestPending, low1.Int());
sl@0
  1966
	test_Equal(KRequestPending, low2.Int());
sl@0
  1967
	test_Equal(KRequestPending, low4.Int());
sl@0
  1968
	test_Equal(KRequestPending, low5.Int());
sl@0
  1969
	sem.Signal();
sl@0
  1970
	User::WaitForRequest(low2, threadrs);
sl@0
  1971
	test_KErrNone(low2.Int())
sl@0
  1972
	test_Equal(KRequestPending, low1.Int());
sl@0
  1973
	test_Equal(KRequestPending, low4.Int());
sl@0
  1974
	test_Equal(KRequestPending, low5.Int());
sl@0
  1975
	sem.Signal();
sl@0
  1976
	User::WaitForRequest(low1, threadrs);
sl@0
  1977
	test_KErrNone(low1.Int());
sl@0
  1978
	User::WaitForRequest(low4, threadrs);
sl@0
  1979
	test_KErrNone(low4.Int());
sl@0
  1980
	test_Equal(KRequestPending, low5.Int());
sl@0
  1981
	test_Equal(EExitPending, thread.ExitType()); // Thread is still running
sl@0
  1982
	test_Compare(aPool.FreeCount(), <=, 1);
sl@0
  1983
sl@0
  1984
	test.Printf(_L("Free space notification\n"));
sl@0
  1985
	TRequestStatus free1;
sl@0
  1986
	TRequestStatus free2;
sl@0
  1987
	TRequestStatus free3;
sl@0
  1988
	TRequestStatus free4;
sl@0
  1989
	TRequestStatus free5;
sl@0
  1990
	TRequestStatus free6;
sl@0
  1991
	aPool.RequestFreeSpaceNotification(KTestPoolSizeInBufs, free1);
sl@0
  1992
	test_Equal(KRequestPending, free1.Int());
sl@0
  1993
	aPool.RequestFreeSpaceNotification(KTestPoolSizeInBufs - 1, free2);
sl@0
  1994
	test_Equal(KRequestPending, free2.Int());
sl@0
  1995
	aPool.RequestFreeSpaceNotification(aPool.FreeCount() + 1, free3);
sl@0
  1996
	test_Equal(KRequestPending, free3.Int());
sl@0
  1997
	aPool.RequestFreeSpaceNotification(KTestPoolSizeInBufs, free4);
sl@0
  1998
	test_Equal(KRequestPending, free4.Int());
sl@0
  1999
	aPool.RequestFreeSpaceNotification(KTestPoolSizeInBufs + 1, free5); // Never completes
sl@0
  2000
	test_Equal(KRequestPending, free5.Int());
sl@0
  2001
	aPool.RequestFreeSpaceNotification(0, free6); // Completes instantly
sl@0
  2002
sl@0
  2003
	TRequestStatus timeoutfree;
sl@0
  2004
	timer.After(timeoutfree, 5000000); // 5 seconds time out
sl@0
  2005
	User::WaitForRequest(free6, timeoutfree);
sl@0
  2006
	test_KErrNone(free6.Int());
sl@0
  2007
sl@0
  2008
	test_Equal(KRequestPending, free1.Int());
sl@0
  2009
	test_Equal(KRequestPending, free2.Int());
sl@0
  2010
	test_Equal(KRequestPending, free3.Int());
sl@0
  2011
	test_Equal(KRequestPending, free4.Int());
sl@0
  2012
	test_Equal(KRequestPending, free5.Int());
sl@0
  2013
sl@0
  2014
	timer.Cancel();
sl@0
  2015
	User::WaitForRequest(timeoutfree);
sl@0
  2016
sl@0
  2017
	sem.Signal();	// resume thread execution
sl@0
  2018
	User::WaitForRequest(free3, threadrs);
sl@0
  2019
	test_KErrNone(free3.Int());
sl@0
  2020
	test_Equal(KRequestPending, free1.Int());
sl@0
  2021
	test_Equal(KRequestPending, free2.Int());
sl@0
  2022
	test_Equal(KRequestPending, free4.Int());
sl@0
  2023
	test_Equal(KRequestPending, free5.Int());
sl@0
  2024
sl@0
  2025
	sem.Signal();
sl@0
  2026
	User::WaitForRequest(free2, threadrs);
sl@0
  2027
	test_KErrNone(free2.Int())
sl@0
  2028
sl@0
  2029
	test_Equal(KRequestPending, free1.Int());
sl@0
  2030
	test_Equal(KRequestPending, free4.Int());
sl@0
  2031
	test_Equal(KRequestPending, free5.Int());
sl@0
  2032
	sem.Signal();
sl@0
  2033
sl@0
  2034
	User::WaitForRequest(free1, threadrs);
sl@0
  2035
	test_KErrNone(free1.Int());
sl@0
  2036
	test_KErrNone(free4.Int());
sl@0
  2037
sl@0
  2038
	test_Equal(KRequestPending, free5.Int());
sl@0
  2039
	test_Equal(EExitPending, thread.ExitType()); // Thread is still running
sl@0
  2040
sl@0
  2041
	test_Compare(aPool.FreeCount(), >=, KTestPoolSizeInBufs);
sl@0
  2042
sl@0
  2043
	// Complete the requests still pending...
sl@0
  2044
	aPool.CancelLowSpaceNotification(low5);
sl@0
  2045
	User::WaitForRequest(low5);
sl@0
  2046
sl@0
  2047
	aPool.CancelFreeSpaceNotification(free5);
sl@0
  2048
	User::WaitForRequest(free5);
sl@0
  2049
sl@0
  2050
	// Let thread complete
sl@0
  2051
	sem.Signal();
sl@0
  2052
	User::WaitForRequest(threadrs);
sl@0
  2053
	test_Equal(EExitKill, thread.ExitType());
sl@0
  2054
	test_KErrNone(thread.ExitReason());
sl@0
  2055
	thread.Close();
sl@0
  2056
	sem.Close();
sl@0
  2057
	timer.Close();
sl@0
  2058
	}
sl@0
  2059
sl@0
  2060
/*
sl@0
  2061
@SYMTestCaseID				9
sl@0
  2062
@SYMTestCaseDesc			Cancel low- and free-space notifications
sl@0
  2063
@SYMREQ						REQ11423
sl@0
  2064
@SYMTestActions
sl@0
  2065
	Set Low/High LowSpace Notifications.
sl@0
  2066
	Cancel them.
sl@0
  2067
@SYMTestExpectedResults
sl@0
  2068
	All OK.
sl@0
  2069
@SYMTestPriority			Medium
sl@0
  2070
*/
sl@0
  2071
sl@0
  2072
void CancelNotificationRequests(RShPool& aPool)
sl@0
  2073
	{
sl@0
  2074
	test.Next(_L("Cancel notifications"));
sl@0
  2075
	TInt r;
sl@0
  2076
sl@0
  2077
	RSemaphore sem;
sl@0
  2078
	r = sem.CreateGlobal(KTestLowSpaceSemaphore, 0);
sl@0
  2079
	test_KErrNone(r);
sl@0
  2080
	RThread thread;
sl@0
  2081
	TRequestStatus threadrs;
sl@0
  2082
	r = thread.Create(_L("ThreadCancelNotifications"), ThreadNotifications, KDefaultStackSize, KMinHeapSize, 1 << 20, (TAny*) &aPool);
sl@0
  2083
	test_KErrNone(r);
sl@0
  2084
	thread.SetPriority(EPriorityLess);
sl@0
  2085
	thread.Logon(threadrs);
sl@0
  2086
sl@0
  2087
	test.Printf(_L("Cancel low space notifications\n"));
sl@0
  2088
	// Low space notification cancel
sl@0
  2089
	TRequestStatus low;
sl@0
  2090
	aPool.RequestLowSpaceNotification(1, low);
sl@0
  2091
	aPool.CancelLowSpaceNotification(low);
sl@0
  2092
	test_Equal(KErrCancel, low.Int());
sl@0
  2093
	// We should be able to cancel again without panic()ing
sl@0
  2094
	// (no guarantees on return code; maybe Cancel() should have void return type?)
sl@0
  2095
	aPool.CancelLowSpaceNotification(low);
sl@0
  2096
	test.Printf(_L("Second cancel returned %d\n"), low.Int());
sl@0
  2097
	TRequestStatus low2;
sl@0
  2098
	aPool.RequestLowSpaceNotification(1, low2); // For thread sync
sl@0
  2099
	thread.Resume();
sl@0
  2100
	sem.Signal(2);
sl@0
  2101
	User::WaitForRequest(low2, threadrs);
sl@0
  2102
	test_KErrNone(low2.Int());
sl@0
  2103
	test_Equal(EExitPending, thread.ExitType()); // Thread is still running
sl@0
  2104
	test_Compare(aPool.FreeCount(), <=, 1);
sl@0
  2105
sl@0
  2106
	test.Printf(_L("Cancel free space notifications\n"));
sl@0
  2107
	TRequestStatus free;
sl@0
  2108
	aPool.CancelFreeSpaceNotification(free);	// Cancel non-existant notification
sl@0
  2109
	aPool.RequestFreeSpaceNotification(KTestPoolSizeInBufs, free);
sl@0
  2110
	aPool.CancelLowSpaceNotification(free);		// Use wrong method
sl@0
  2111
	aPool.CancelFreeSpaceNotification(free);		// Use wrong method
sl@0
  2112
	test_Equal(KErrCancel, free.Int());
sl@0
  2113
	aPool.CancelFreeSpaceNotification(free);		// Already cancelled
sl@0
  2114
sl@0
  2115
	// Complete the requests still pending...
sl@0
  2116
	User::WaitForRequest(low);
sl@0
  2117
sl@0
  2118
	sem.Signal(4); // Resume thread execution and let it complete
sl@0
  2119
	User::WaitForRequest(threadrs);
sl@0
  2120
	test_KErrNone(threadrs.Int());
sl@0
  2121
	test_Equal(EExitKill, thread.ExitType());
sl@0
  2122
	test_KErrNone(thread.ExitReason());
sl@0
  2123
	test_Compare(aPool.FreeCount(), >=, KTestPoolSizeInBufs);
sl@0
  2124
	thread.Close();
sl@0
  2125
	sem.Close();
sl@0
  2126
	}
sl@0
  2127
sl@0
  2128
sl@0
  2129
/*
sl@0
  2130
@SYMTestCaseID				10
sl@0
  2131
@SYMTestCaseDesc			Grow and shrink pool
sl@0
  2132
@SYMREQ						REQ11423
sl@0
  2133
@SYMTestActions
sl@0
  2134
	1. Test Thread creates pools with various size attributes
sl@0
  2135
	2. Test Thread keeps allocating buffers on pool.
sl@0
  2136
	3. Test Thread keeps freeing buffers on pool
sl@0
  2137
	4. Test Thread frees all buffers and close pool.
sl@0
  2138
@SYMTestExpectedResults
sl@0
  2139
	Pools grows and shrink grows as expected.
sl@0
  2140
@SYMTestPriority			High
sl@0
  2141
*/
sl@0
  2142
sl@0
  2143
const TInt KTestFreeCountTimeOut = 20000000; // 20 seconds (of thread inactivity)
sl@0
  2144
const TInt KTestWaitBeforeRetry = 2000; // 0.002 second
sl@0
  2145
sl@0
  2146
TUint MultFx248(TUint n, TUint f)
sl@0
  2147
	{
sl@0
  2148
	TUint64 r = (TUint64) n * f;
sl@0
  2149
	I64LSR(r, 8);
sl@0
  2150
	return r > KMaxTUint32 ? KMaxTUint32 : I64LOW(r);
sl@0
  2151
	}
sl@0
  2152
sl@0
  2153
class TTestPoolModel
sl@0
  2154
	{
sl@0
  2155
public:
sl@0
  2156
	TTestPoolModel(TShPoolInfo& aInfo);
sl@0
  2157
	void Alloc();
sl@0
  2158
	void Free();
sl@0
  2159
	TUint FreeCount();
sl@0
  2160
	void DisplayCounters();
sl@0
  2161
private:
sl@0
  2162
	void CalcGSP();
sl@0
  2163
	void CheckGrowShrink();
sl@0
  2164
	void Grow();
sl@0
  2165
	void Shrink();
sl@0
  2166
private:
sl@0
  2167
	TUint iAllocated;
sl@0
  2168
	TUint iFree;
sl@0
  2169
	//
sl@0
  2170
	TUint iInitial;
sl@0
  2171
	TUint iMax;
sl@0
  2172
	TUint iGrowTriggerRatio;
sl@0
  2173
	TUint iGrowByRatio;
sl@0
  2174
	TUint iShrinkByRatio;
sl@0
  2175
	TUint iShrinkHysteresisRatio;
sl@0
  2176
	TUint iPoolFlags;
sl@0
  2177
	//
sl@0
  2178
	TUint iGrowTrigger;
sl@0
  2179
	TUint iShrinkTrigger;
sl@0
  2180
	//
sl@0
  2181
	TBool iDebug;
sl@0
  2182
	};
sl@0
  2183
sl@0
  2184
TTestPoolModel::TTestPoolModel(TShPoolInfo& aInfo)
sl@0
  2185
	{
sl@0
  2186
	iInitial = aInfo.iInitialBufs;
sl@0
  2187
	iMax = aInfo.iMaxBufs;
sl@0
  2188
	iGrowTriggerRatio = aInfo.iGrowTriggerRatio;
sl@0
  2189
	iGrowByRatio = aInfo.iGrowByRatio;
sl@0
  2190
	iShrinkByRatio = 256 - 65536 / (256 + iGrowByRatio);
sl@0
  2191
	iShrinkHysteresisRatio = aInfo.iShrinkHysteresisRatio;
sl@0
  2192
	iPoolFlags = aInfo.iFlags;
sl@0
  2193
	iAllocated = 0;
sl@0
  2194
	iFree = iInitial;
sl@0
  2195
	iDebug = EFalse; // Set this to ETrue to display detailed information
sl@0
  2196
	
sl@0
  2197
	CalcGSP();
sl@0
  2198
	if (iDebug)
sl@0
  2199
		{
sl@0
  2200
		test.Printf(_L("A     F     A+F   GT    ST    \n"));
sl@0
  2201
		test.Printf(_L("==============================\n"));
sl@0
  2202
		DisplayCounters();
sl@0
  2203
		}
sl@0
  2204
	}
sl@0
  2205
sl@0
  2206
void TTestPoolModel::Alloc()
sl@0
  2207
	{
sl@0
  2208
	iAllocated++;
sl@0
  2209
	iFree--;
sl@0
  2210
	CheckGrowShrink();
sl@0
  2211
	}
sl@0
  2212
sl@0
  2213
void TTestPoolModel::Free()
sl@0
  2214
	{
sl@0
  2215
	iAllocated--;
sl@0
  2216
	iFree++;
sl@0
  2217
	CheckGrowShrink();
sl@0
  2218
	}
sl@0
  2219
sl@0
  2220
TUint TTestPoolModel::FreeCount()
sl@0
  2221
	{
sl@0
  2222
	return iFree;
sl@0
  2223
	}
sl@0
  2224
sl@0
  2225
void TTestPoolModel::CalcGSP()
sl@0
  2226
	{
sl@0
  2227
	TUint n = iAllocated + iFree;
sl@0
  2228
sl@0
  2229
	// If the pool is at its maximum size, we can't grow
sl@0
  2230
	if (n >= iMax || iGrowTriggerRatio == 0 /*|| iCommittedPages >= iMaxPages*/)
sl@0
  2231
		{
sl@0
  2232
		iGrowTrigger = 0;
sl@0
  2233
		}
sl@0
  2234
	else
sl@0
  2235
		{
sl@0
  2236
		iGrowTrigger = MultFx248(n, iGrowTriggerRatio);
sl@0
  2237
sl@0
  2238
		// Deal with rounding towards zero
sl@0
  2239
		if (iGrowTrigger == 0)
sl@0
  2240
			iGrowTrigger = 1;
sl@0
  2241
		}
sl@0
  2242
sl@0
  2243
	// If no growing has happened, we can't shrink
sl@0
  2244
	if (n <= iInitial || iGrowTriggerRatio == 0 || (iPoolFlags & EShPoolSuppressShrink) != 0)
sl@0
  2245
		{
sl@0
  2246
		iShrinkTrigger = iMax;
sl@0
  2247
		}
sl@0
  2248
	else
sl@0
  2249
		{
sl@0
  2250
		// To ensure that shrinking doesn't immediately happen after growing, the trigger
sl@0
  2251
		// amount is the grow trigger + the grow amount (which is the number of free buffers
sl@0
  2252
		// just after a grow) times the shrink hysteresis value.
sl@0
  2253
		iShrinkTrigger = MultFx248(n, iGrowTriggerRatio + iGrowByRatio);
sl@0
  2254
		iShrinkTrigger = MultFx248(iShrinkTrigger, iShrinkHysteresisRatio);
sl@0
  2255
sl@0
  2256
		// Deal with rounding towards zero
sl@0
  2257
		if (iShrinkTrigger == 0)
sl@0
  2258
			iShrinkTrigger = 1;
sl@0
  2259
sl@0
  2260
		// If the shrink trigger ends up > the number of buffers currently in
sl@0
  2261
		// the pool, set it to that number (less 1, since the test is "> trigger").
sl@0
  2262
		// This means the pool will only shrink when all the buffers have been freed.
sl@0
  2263
		if (iShrinkTrigger >= n)
sl@0
  2264
			iShrinkTrigger = n - 1;
sl@0
  2265
		}
sl@0
  2266
	if (iDebug)
sl@0
  2267
		{
sl@0
  2268
		DisplayCounters();
sl@0
  2269
		}
sl@0
  2270
	}
sl@0
  2271
sl@0
  2272
void TTestPoolModel::CheckGrowShrink()
sl@0
  2273
	{
sl@0
  2274
	if (iFree < iGrowTrigger)
sl@0
  2275
		{
sl@0
  2276
		Grow();
sl@0
  2277
		CheckGrowShrink();
sl@0
  2278
		}
sl@0
  2279
	if (iFree > iShrinkTrigger)
sl@0
  2280
		{
sl@0
  2281
		Shrink();
sl@0
  2282
		CheckGrowShrink();
sl@0
  2283
		}
sl@0
  2284
	}
sl@0
  2285
sl@0
  2286
void TTestPoolModel::Grow()
sl@0
  2287
	{
sl@0
  2288
	TUint headroom = iMax - (iAllocated + iFree);
sl@0
  2289
	TUint growby = MultFx248(iAllocated + iFree, iGrowByRatio);
sl@0
  2290
	if (growby == 0)			// Handle round-to-zero
sl@0
  2291
		growby = 1;
sl@0
  2292
	if (growby > headroom)
sl@0
  2293
		growby = headroom;
sl@0
  2294
	iFree += growby;
sl@0
  2295
	if (iDebug)
sl@0
  2296
		{
sl@0
  2297
		test.Printf(_L("GROW by %d!\n"), growby);
sl@0
  2298
		}
sl@0
  2299
	CalcGSP();
sl@0
  2300
	}
sl@0
  2301
sl@0
  2302
void TTestPoolModel::Shrink()
sl@0
  2303
	{
sl@0
  2304
	TUint grownBy = iAllocated + iFree - iInitial;
sl@0
  2305
	TUint shrinkby = MultFx248(iAllocated + iFree, iShrinkByRatio);
sl@0
  2306
	if (shrinkby == 0)			// Handle round-to-zero
sl@0
  2307
		shrinkby = 1;
sl@0
  2308
	if (shrinkby > grownBy)
sl@0
  2309
		shrinkby = grownBy;
sl@0
  2310
	if (shrinkby > iFree)
sl@0
  2311
		shrinkby = iFree;
sl@0
  2312
	iFree -= shrinkby;
sl@0
  2313
	if (iDebug)
sl@0
  2314
		{
sl@0
  2315
		test.Printf(_L("SHRINK by %d!\n"), shrinkby);
sl@0
  2316
		}
sl@0
  2317
	CalcGSP();
sl@0
  2318
	}
sl@0
  2319
sl@0
  2320
void TTestPoolModel::DisplayCounters()
sl@0
  2321
	{
sl@0
  2322
	test.Printf(_L("%-6u%-6u%-6u%-6u%-6u\n"), iAllocated, iFree, iAllocated + iFree, iGrowTrigger, iShrinkTrigger);
sl@0
  2323
	}
sl@0
  2324
sl@0
  2325
void PoolGrowingTestRoutine(const TShPoolCreateInfo& aInfo, TUint aBufferFlags = 0)
sl@0
  2326
	{
sl@0
  2327
	TInt r;
sl@0
  2328
	TInt timeout;
sl@0
  2329
	RShPool pool;
sl@0
  2330
	r = pool.Create(aInfo, KDefaultPoolHandleFlags);
sl@0
  2331
	test_KErrNone(r);
sl@0
  2332
sl@0
  2333
	TShPoolInfo info;
sl@0
  2334
	pool.GetInfo(info);
sl@0
  2335
sl@0
  2336
	// Only set the buffer window if we're going to map the buffers
sl@0
  2337
	if (!(aBufferFlags & EShPoolAllocNoMap) && (info.iFlags & EShPoolPageAlignedBuffer))
sl@0
  2338
		{
sl@0
  2339
		r = pool.SetBufferWindow(-1, ETrue);
sl@0
  2340
		test_KErrNone(r)
sl@0
  2341
		}
sl@0
  2342
sl@0
  2343
	TTestPoolModel model(info);
sl@0
  2344
	RArray<RShBuf> bufarray;
sl@0
  2345
	test_Equal(info.iInitialBufs, pool.FreeCount());
sl@0
  2346
sl@0
  2347
	// Buffer allocation
sl@0
  2348
	do
sl@0
  2349
		{
sl@0
  2350
		timeout = KTestFreeCountTimeOut / KTestWaitBeforeRetry;
sl@0
  2351
		while (model.FreeCount() != pool.FreeCount())
sl@0
  2352
			{
sl@0
  2353
			User::After(KTestWaitBeforeRetry);
sl@0
  2354
			test_Assert(--timeout,
sl@0
  2355
				test.Printf(_L("Timeout: Free==%u (expected %u)\n"), pool.FreeCount(), model.FreeCount());
sl@0
  2356
				model.DisplayCounters();
sl@0
  2357
				);
sl@0
  2358
			if ((timeout * KTestWaitBeforeRetry) % 1000000 == 0)
sl@0
  2359
				{
sl@0
  2360
				test.Printf(_L("Time out in %d seconds! (line %d)\n"), timeout * KTestWaitBeforeRetry / 1000000, __LINE__);
sl@0
  2361
				}
sl@0
  2362
			}
sl@0
  2363
		RShBuf buf;
sl@0
  2364
		r = buf.Alloc(pool, aBufferFlags);
sl@0
  2365
		if (r == KErrNoMemory)
sl@0
  2366
			{
sl@0
  2367
			// We expect to get a failure when all buffers are allocated
sl@0
  2368
			if ((TUint) bufarray.Count() == info.iMaxBufs)
sl@0
  2369
				break;
sl@0
  2370
			if (!(aBufferFlags & EShPoolAllocCanWait))
sl@0
  2371
				{
sl@0
  2372
				// Give the Management DFC some time to run, then try allocating again
sl@0
  2373
				User::After(1000000); // 1 second
sl@0
  2374
				r = buf.Alloc(pool);
sl@0
  2375
				if (r)
sl@0
  2376
					{
sl@0
  2377
					test.Printf(_L("Alloc fail after %d of %d; Free==%u (expected %u)\n"),
sl@0
  2378
						bufarray.Count(), info.iMaxBufs, pool.FreeCount(), model.FreeCount());
sl@0
  2379
					break;
sl@0
  2380
					}
sl@0
  2381
				}
sl@0
  2382
			}
sl@0
  2383
sl@0
  2384
		if (r == KErrNone)
sl@0
  2385
			{
sl@0
  2386
			model.Alloc();
sl@0
  2387
			if (!(aBufferFlags & EShPoolAllocNoMap))
sl@0
  2388
				{
sl@0
  2389
				TPtr8 ptr(buf.Ptr(), buf.Size(),buf.Size());
sl@0
  2390
				ptr.Fill(bufarray.Count() % 256);
sl@0
  2391
				}
sl@0
  2392
			bufarray.Append(buf);
sl@0
  2393
			}
sl@0
  2394
		}
sl@0
  2395
	while (r == KErrNone);
sl@0
  2396
sl@0
  2397
	test_Equal(KErrNoMemory, r);
sl@0
  2398
	test_Equal(info.iMaxBufs, bufarray.Count());
sl@0
  2399
	test_Equal(0, pool.FreeCount());
sl@0
  2400
sl@0
  2401
	// Now free no more than 1/3 of these buffers...
sl@0
  2402
	while ((TUint) bufarray.Count() > 2 * info.iMaxBufs / 3)
sl@0
  2403
		{
sl@0
  2404
		// remove buffers from the back of the array
sl@0
  2405
		if (!(aBufferFlags & EShPoolAllocNoMap))
sl@0
  2406
			{
sl@0
  2407
			TPtr8 ptr(bufarray[bufarray.Count() - 1].Ptr(), bufarray[bufarray.Count() - 1].Size(),bufarray[bufarray.Count() - 1].Size());
sl@0
  2408
			ptr.Fill((bufarray.Count() + 1) % 256);
sl@0
  2409
			}
sl@0
  2410
		bufarray[bufarray.Count() - 1].Close();
sl@0
  2411
		bufarray.Remove(bufarray.Count() - 1);
sl@0
  2412
		model.Free();
sl@0
  2413
		
sl@0
  2414
		timeout = KTestFreeCountTimeOut / KTestWaitBeforeRetry;
sl@0
  2415
		while (model.FreeCount() != pool.FreeCount())
sl@0
  2416
			{
sl@0
  2417
			User::After(KTestWaitBeforeRetry);
sl@0
  2418
			test_Assert(--timeout,
sl@0
  2419
				test.Printf(_L("Timeout: Free==%u (expected %u)\n"), pool.FreeCount(), model.FreeCount());
sl@0
  2420
				model.DisplayCounters();
sl@0
  2421
				);
sl@0
  2422
			if ((timeout * KTestWaitBeforeRetry) % 1000000 == 0)
sl@0
  2423
				{
sl@0
  2424
				test.Printf(_L("Time out in %d seconds! (line %d)\n"), timeout * KTestWaitBeforeRetry / 1000000, __LINE__);
sl@0
  2425
				}
sl@0
  2426
			}
sl@0
  2427
		}
sl@0
  2428
sl@0
  2429
	// ... and re-allocate them
sl@0
  2430
	do
sl@0
  2431
		{
sl@0
  2432
		timeout = KTestFreeCountTimeOut / KTestWaitBeforeRetry;
sl@0
  2433
		while (model.FreeCount() != pool.FreeCount())
sl@0
  2434
			{
sl@0
  2435
			User::After(KTestWaitBeforeRetry);
sl@0
  2436
			test_Assert(--timeout,
sl@0
  2437
				test.Printf(_L("Timeout: Free==%u (expected %u)\n"), pool.FreeCount(), model.FreeCount());
sl@0
  2438
				model.DisplayCounters();
sl@0
  2439
				);
sl@0
  2440
			if ((timeout * KTestWaitBeforeRetry) % 1000000 == 0)
sl@0
  2441
				{
sl@0
  2442
				test.Printf(_L("Time out in %d seconds! (line %d)\n"), timeout * KTestWaitBeforeRetry / 1000000, __LINE__);
sl@0
  2443
				}
sl@0
  2444
			}
sl@0
  2445
		RShBuf buf;
sl@0
  2446
		r = buf.Alloc(pool, aBufferFlags);
sl@0
  2447
		if (r == KErrNoMemory)
sl@0
  2448
			{
sl@0
  2449
			// We expect to get a failure when all buffers are allocated
sl@0
  2450
			if ((TUint) bufarray.Count() == info.iMaxBufs)
sl@0
  2451
				break;
sl@0
  2452
			if (!(aBufferFlags & EShPoolAllocCanWait))
sl@0
  2453
				{
sl@0
  2454
				// Give the Management DFC some time to run, then try allocating again
sl@0
  2455
				User::After(1000000); // 1 second
sl@0
  2456
				r = buf.Alloc(pool);
sl@0
  2457
				if (r)
sl@0
  2458
					{
sl@0
  2459
					test.Printf(_L("Alloc fail after %d of %d; Free==%u (expected %u)\n"),
sl@0
  2460
						bufarray.Count(), info.iMaxBufs, pool.FreeCount(), model.FreeCount());
sl@0
  2461
					break;
sl@0
  2462
					}
sl@0
  2463
				}
sl@0
  2464
			}
sl@0
  2465
sl@0
  2466
		if (r == KErrNone)
sl@0
  2467
			{
sl@0
  2468
			model.Alloc();
sl@0
  2469
			if (!(aBufferFlags & EShPoolAllocNoMap))
sl@0
  2470
				{
sl@0
  2471
				TPtr8 ptr(buf.Ptr(), buf.Size(),buf.Size());
sl@0
  2472
				ptr.Fill(bufarray.Count() % 256);
sl@0
  2473
				}
sl@0
  2474
			bufarray.Append(buf);
sl@0
  2475
			}
sl@0
  2476
		}
sl@0
  2477
	while (r == KErrNone);
sl@0
  2478
sl@0
  2479
	test_Equal(KErrNoMemory, r);
sl@0
  2480
	test_Equal(info.iMaxBufs, bufarray.Count());
sl@0
  2481
	test_Equal(0, pool.FreeCount());
sl@0
  2482
sl@0
  2483
	// Free all buffers
sl@0
  2484
	while (bufarray.Count())
sl@0
  2485
		{
sl@0
  2486
		// remove buffers from the back of the array
sl@0
  2487
		if (!(aBufferFlags & EShPoolAllocNoMap))
sl@0
  2488
			{
sl@0
  2489
			TPtr8 ptr(bufarray[bufarray.Count() - 1].Ptr(), bufarray[bufarray.Count() - 1].Size(),bufarray[bufarray.Count() - 1].Size());
sl@0
  2490
			ptr.Fill((bufarray.Count() + 1) % 256);
sl@0
  2491
			}
sl@0
  2492
		bufarray[bufarray.Count() - 1].Close();
sl@0
  2493
		bufarray.Remove(bufarray.Count() - 1);
sl@0
  2494
		model.Free();
sl@0
  2495
		
sl@0
  2496
		timeout = KTestFreeCountTimeOut / KTestWaitBeforeRetry;
sl@0
  2497
		while (model.FreeCount() != pool.FreeCount())
sl@0
  2498
			{
sl@0
  2499
			User::After(KTestWaitBeforeRetry);
sl@0
  2500
			test_Assert(--timeout,
sl@0
  2501
				test.Printf(_L("Timeout: Free==%u (expected %u)\n"), pool.FreeCount(), model.FreeCount());
sl@0
  2502
				model.DisplayCounters();
sl@0
  2503
				);
sl@0
  2504
			if ((timeout * KTestWaitBeforeRetry) % 1000000 == 0)
sl@0
  2505
				{
sl@0
  2506
				test.Printf(_L("Time out in %d seconds! (line %d)\n"), timeout * KTestWaitBeforeRetry / 1000000, __LINE__);
sl@0
  2507
				}
sl@0
  2508
			}
sl@0
  2509
		}
sl@0
  2510
sl@0
  2511
	// Pool should have shrunk back to its initial size
sl@0
  2512
	test_Equal(info.iInitialBufs, pool.FreeCount());
sl@0
  2513
	bufarray.Close();
sl@0
  2514
	pool.Close();
sl@0
  2515
	}
sl@0
  2516
sl@0
  2517
void PoolGrowingUser()
sl@0
  2518
	{
sl@0
  2519
	test.Next(_L("Pool Growing/Shrinking (User)"));
sl@0
  2520
	TInt r;
sl@0
  2521
	TInt pagesize;
sl@0
  2522
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
  2523
	test_KErrNone(r);
sl@0
  2524
	// Pool A: Non-page aligned pool (64-byte alignment)
sl@0
  2525
		{
sl@0
  2526
		TInt alignment = 6;
sl@0
  2527
		TInt maxbufs = KTestPoolSizeInBytes / RoundUp(*PtrBufSize, alignment);
sl@0
  2528
		if (maxbufs > 32000)
sl@0
  2529
			{
sl@0
  2530
			maxbufs = 32000;
sl@0
  2531
			}
sl@0
  2532
		TInt initialbufs = maxbufs / 2;
sl@0
  2533
		TInt growtrigger = 32;
sl@0
  2534
		TInt growby = 32;
sl@0
  2535
		TInt shrinkhys = 288;
sl@0
  2536
		test.Printf(_L("POOL A: BufSize=%d InitialBufs=%d MaxBufs=%d GrowTrigger=%d GrowBy=%d ShrinkHys=%d Alignment=%d\n"),
sl@0
  2537
			*PtrBufSize, initialbufs, maxbufs, growtrigger, growby, shrinkhys, alignment);
sl@0
  2538
		TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize, initialbufs, alignment);
sl@0
  2539
		r = inf.SetSizingAttributes(maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2540
		test_KErrNone(r);
sl@0
  2541
		PoolGrowingTestRoutine(inf);
sl@0
  2542
		}
sl@0
  2543
sl@0
  2544
	// Pool B: Non-page aligned pool (maximum alignment)
sl@0
  2545
		{
sl@0
  2546
		TInt alignment = Log2(pagesize);
sl@0
  2547
		TInt maxbufs = KTestPoolSizeInBytes / RoundUp(*PtrBufSize, alignment);
sl@0
  2548
		if (maxbufs > 32000)
sl@0
  2549
			{
sl@0
  2550
			maxbufs = 32000;
sl@0
  2551
			}
sl@0
  2552
		TInt initialbufs = maxbufs / 4;
sl@0
  2553
		TInt growtrigger = 32;
sl@0
  2554
		TInt growby = 32;
sl@0
  2555
		TInt shrinkhys = 288;
sl@0
  2556
		test.Printf(_L("POOL B: BufSize=%d InitialBufs=%d MaxBufs=%d GrowTrigger=%d GrowBy=%d ShrinkHys=%d Alignment=%d\n"),
sl@0
  2557
			*PtrBufSize, initialbufs, maxbufs, growtrigger, growby, shrinkhys, alignment);
sl@0
  2558
		TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize, initialbufs, alignment);
sl@0
  2559
		r = inf.SetSizingAttributes(maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2560
		test_KErrNone(r);
sl@0
  2561
		PoolGrowingTestRoutine(inf);
sl@0
  2562
		}
sl@0
  2563
	
sl@0
  2564
	// Pool C: Page aligned pool without guard pages
sl@0
  2565
		{
sl@0
  2566
		TInt maxbufs = KTestPoolSizeInBytes / RoundUp(*PtrBufSize, Log2(pagesize));
sl@0
  2567
		if (maxbufs > 32000)
sl@0
  2568
			{
sl@0
  2569
			maxbufs = 32000;
sl@0
  2570
			}
sl@0
  2571
		TInt initialbufs = maxbufs * 3 / 8;
sl@0
  2572
		TInt growtrigger = 32;
sl@0
  2573
		TInt growby = 32;
sl@0
  2574
		TInt shrinkhys = 288;
sl@0
  2575
		test.Printf(_L("POOL C: BufSize=%d InitialBufs=%d MaxBufs=%d GrowTrigger=%d GrowBy=%d ShrinkHys=%d Page-Aligned\n"),
sl@0
  2576
			*PtrBufSize, initialbufs, maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2577
		TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, initialbufs);
sl@0
  2578
		r = inf.SetSizingAttributes(maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2579
		test_KErrNone(r);
sl@0
  2580
		PoolGrowingTestRoutine(inf);
sl@0
  2581
		}
sl@0
  2582
sl@0
  2583
	// Pool D: Page aligned pool without guard pages
sl@0
  2584
		{
sl@0
  2585
		TInt maxbufs = KTestPoolSizeInBytes / RoundUp(*PtrBufSize, Log2(pagesize));
sl@0
  2586
		if (maxbufs > 32000)
sl@0
  2587
			{
sl@0
  2588
			maxbufs = 32000;
sl@0
  2589
			}
sl@0
  2590
		TInt initialbufs = maxbufs / 2;
sl@0
  2591
		TInt growtrigger = 32;
sl@0
  2592
		TInt growby = 32;
sl@0
  2593
		TInt shrinkhys = 288;
sl@0
  2594
		test.Printf(_L("POOL D: BufSize=%d InitialBufs=%d MaxBufs=%d GrowTrigger=%d GrowBy=%d ShrinkHys=%d Page-Aligned+Guard\n"),
sl@0
  2595
			*PtrBufSize, initialbufs, maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2596
		TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, initialbufs);
sl@0
  2597
		r = inf.SetSizingAttributes(maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2598
		test_KErrNone(r);
sl@0
  2599
		r = inf.SetGuardPages();
sl@0
  2600
		test_KErrNone(r);
sl@0
  2601
		PoolGrowingTestRoutine(inf);
sl@0
  2602
		}
sl@0
  2603
sl@0
  2604
	// Pool A': Non-page aligned pool (64-byte alignment)
sl@0
  2605
		{
sl@0
  2606
		TInt alignment = 6;
sl@0
  2607
		TInt maxbufs = KTestPoolSizeInBytes / RoundUp(*PtrBufSize, alignment);
sl@0
  2608
		if (maxbufs > 32000)
sl@0
  2609
			{
sl@0
  2610
			maxbufs = 32000;
sl@0
  2611
			}
sl@0
  2612
		TInt initialbufs = 1;
sl@0
  2613
		TInt growtrigger = 32;
sl@0
  2614
		TInt growby = 256;
sl@0
  2615
		TInt shrinkhys = 512;
sl@0
  2616
		test.Printf(_L("POOL A': BufSize=%d InitialBufs=%d MaxBufs=%d GrowTrigger=%d GrowBy=%d ShrinkHys=%d Alignment=%d\n"),
sl@0
  2617
			*PtrBufSize, initialbufs, maxbufs, growtrigger, growby, shrinkhys, alignment);
sl@0
  2618
		TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize, initialbufs, alignment);
sl@0
  2619
		r = inf.SetSizingAttributes(maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2620
		test_KErrNone(r);
sl@0
  2621
		PoolGrowingTestRoutine(inf);
sl@0
  2622
		}
sl@0
  2623
sl@0
  2624
	// Pool A'': Non-page aligned pool (64-byte alignment) - AllocCanWait
sl@0
  2625
		{
sl@0
  2626
		TInt alignment = 6;
sl@0
  2627
		TInt maxbufs = KTestPoolSizeInBytes / RoundUp(*PtrBufSize, alignment);
sl@0
  2628
		if (maxbufs > 32000)
sl@0
  2629
			{
sl@0
  2630
			maxbufs = 32000;
sl@0
  2631
			}
sl@0
  2632
		TInt initialbufs = 1;
sl@0
  2633
		TInt growtrigger = 1;
sl@0
  2634
		TInt growby = 1;
sl@0
  2635
		TInt shrinkhys = 257;
sl@0
  2636
		test.Printf(_L("POOL A'': BufSize=%d InitialBufs=%d MaxBufs=%d GrowTrigger=%d GrowBy=%d ShrinkHys=%d Alignment=%d\n"),
sl@0
  2637
			*PtrBufSize, initialbufs, maxbufs, growtrigger, growby, shrinkhys, alignment);
sl@0
  2638
		TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize, initialbufs, alignment);
sl@0
  2639
		r = inf.SetSizingAttributes(maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2640
		test_KErrNone(r);
sl@0
  2641
		PoolGrowingTestRoutine(inf, EShPoolAllocCanWait);
sl@0
  2642
		}
sl@0
  2643
sl@0
  2644
	// Pool D': Page aligned pool without guard pages
sl@0
  2645
		{
sl@0
  2646
		TInt maxbufs = KTestPoolSizeInBytes / RoundUp(*PtrBufSize, Log2(pagesize));
sl@0
  2647
		if (maxbufs > 32000)
sl@0
  2648
			{
sl@0
  2649
			maxbufs = 32000;
sl@0
  2650
			}
sl@0
  2651
		TInt initialbufs = 1;
sl@0
  2652
		TInt growtrigger = 1;
sl@0
  2653
		TInt growby = 1024;
sl@0
  2654
		TInt shrinkhys = 2048;
sl@0
  2655
		test.Printf(_L("POOL D': BufSize=%d InitialBufs=%d MaxBufs=%d GrowTrigger=%d GrowBy=%d ShrinkHys=%d Page-Aligned+Guard\n"),
sl@0
  2656
			*PtrBufSize, initialbufs, maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2657
		TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, initialbufs);
sl@0
  2658
		r = inf.SetSizingAttributes(maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2659
		test_KErrNone(r);
sl@0
  2660
		r = inf.SetGuardPages();
sl@0
  2661
		test_KErrNone(r);
sl@0
  2662
		PoolGrowingTestRoutine(inf);
sl@0
  2663
		}
sl@0
  2664
	// Pool D'': Page aligned pool without guard pages - NoBufferMap
sl@0
  2665
		{
sl@0
  2666
		TInt maxbufs = KTestPoolSizeInBytes / RoundUp(*PtrBufSize, Log2(pagesize));
sl@0
  2667
		if (maxbufs > 32000)
sl@0
  2668
			{
sl@0
  2669
			maxbufs = 32000;
sl@0
  2670
			}
sl@0
  2671
		TInt initialbufs = maxbufs / 2;
sl@0
  2672
		TInt growtrigger = 32;
sl@0
  2673
		TInt growby = 32;
sl@0
  2674
		TInt shrinkhys = 288;
sl@0
  2675
		test.Printf(_L("POOL D'': BufSize=%d InitialBufs=%d MaxBufs=%d GrowTrigger=%d GrowBy=%d ShrinkHys=%d Page-Aligned+Guard\n"),
sl@0
  2676
			*PtrBufSize, initialbufs, maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2677
		TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, initialbufs);
sl@0
  2678
		r = inf.SetSizingAttributes(maxbufs, growtrigger, growby, shrinkhys);
sl@0
  2679
		test_KErrNone(r);
sl@0
  2680
		r = inf.SetGuardPages();
sl@0
  2681
		test_KErrNone(r);
sl@0
  2682
		PoolGrowingTestRoutine(inf, EShPoolAllocNoMap);
sl@0
  2683
		}
sl@0
  2684
	}
sl@0
  2685
sl@0
  2686
/*
sl@0
  2687
@SYMTestCaseID				X3
sl@0
  2688
@SYMTestCaseDesc			Contiguous buffer allocation
sl@0
  2689
@SYMREQ						REQ11423
sl@0
  2690
@SYMTestActions
sl@0
  2691
	Create a pool with the Contiguous attribute and allocate buffers.
sl@0
  2692
@SYMTestExpectedResults
sl@0
  2693
	Buffers memory is physically contiguous.
sl@0
  2694
@SYMTestPriority			High
sl@0
  2695
*/
sl@0
  2696
sl@0
  2697
void ContiguousPoolKernel()
sl@0
  2698
	{
sl@0
  2699
	test.Next(_L("Contiguous Pool (Kernel)"));
sl@0
  2700
#ifdef __WINS__
sl@0
  2701
	test.Printf(_L("Does not run on the emulator. Skipped\n"));
sl@0
  2702
#else
sl@0
  2703
	TInt r;
sl@0
  2704
	TInt pagesize;
sl@0
  2705
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
  2706
	test_KErrNone(r);
sl@0
  2707
	if (*PtrBufSize <= pagesize)
sl@0
  2708
		{
sl@0
  2709
		test.Printf(_L("Buffer size <= page size. Skipped.\n"));
sl@0
  2710
		return;
sl@0
  2711
		}
sl@0
  2712
sl@0
  2713
	TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, KTestPoolSizeInBufs);
sl@0
  2714
//	r = inf.SetSizingAttributes(KTestPoolSizeInBufs, 25, 25, 25600);
sl@0
  2715
//	test_KErrNone(r);
sl@0
  2716
sl@0
  2717
	r = Ldd.ContiguousPoolKernel(inf);
sl@0
  2718
	test_KErrNone(r);
sl@0
  2719
sl@0
  2720
#endif // __WINS__
sl@0
  2721
	}
sl@0
  2722
sl@0
  2723
void ShBufPin()
sl@0
  2724
	{
sl@0
  2725
	test.Next(_L("Buffer pinning"));
sl@0
  2726
#ifdef __WINS__
sl@0
  2727
	test.Printf(_L("Does not run on the emulator. Skipped\n"));
sl@0
  2728
#else
sl@0
  2729
	TInt r;
sl@0
  2730
	RShPool pool1;
sl@0
  2731
	RShBuf buf1;
sl@0
  2732
	TShPoolCreateInfo inf1(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize * KTestPoolSizeInBufs, 1, KTestMinimumAlignmentLog2);
sl@0
  2733
	r = pool1.Create(inf1, KDefaultPoolHandleFlags);
sl@0
  2734
	test_KErrNone(r);
sl@0
  2735
	r = buf1.Alloc(pool1);
sl@0
  2736
	test_KErrNone(r);
sl@0
  2737
	r = Ldd.PinBuffer(pool1.Handle(), buf1.Handle());
sl@0
  2738
	test_KErrNone(r);
sl@0
  2739
	buf1.Close();
sl@0
  2740
	pool1.Close();
sl@0
  2741
	
sl@0
  2742
	RShPool pool2;
sl@0
  2743
	RShBuf buf2;
sl@0
  2744
	TShPoolCreateInfo inf2(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize * KTestPoolSizeInBufs, 1, KTestMinimumAlignmentLog2);
sl@0
  2745
	r = pool2.Create(inf2, KDefaultPoolHandleFlags);
sl@0
  2746
	test_KErrNone(r);
sl@0
  2747
	r = buf2.Alloc(pool2);
sl@0
  2748
	test_KErrNone(r);
sl@0
  2749
	r = Ldd.PinBuffer(pool2.Handle(), buf2.Handle());
sl@0
  2750
	test_KErrNone(r);
sl@0
  2751
	buf2.Close();
sl@0
  2752
	pool2.Close();
sl@0
  2753
#endif // _WINS_
sl@0
  2754
	}
sl@0
  2755
sl@0
  2756
/*
sl@0
  2757
@SYMTestCaseID
sl@0
  2758
@SYMTestCaseDesc
sl@0
  2759
@SYMREQ
sl@0
  2760
@SYMTestActions
sl@0
  2761
@SYMTestExpectedResults
sl@0
  2762
@SYMTestPriority
sl@0
  2763
*/
sl@0
  2764
sl@0
  2765
void SingleBufferPool()
sl@0
  2766
	{
sl@0
  2767
	test.Next(_L("Single Buffer Pool"));
sl@0
  2768
	TInt r;
sl@0
  2769
sl@0
  2770
	RShPool pool;
sl@0
  2771
	RShBuf buf;
sl@0
  2772
	RShBuf buf2;
sl@0
  2773
sl@0
  2774
	TShPoolCreateInfo infpa(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize * KTestPoolSizeInBufs, 1);
sl@0
  2775
	r = infpa.SetGuardPages();
sl@0
  2776
	test_KErrNone(r);
sl@0
  2777
	r = pool.Create(infpa, KDefaultPoolHandleFlags);
sl@0
  2778
	test_KErrNone(r);
sl@0
  2779
	r = pool.SetBufferWindow(-1, ETrue);
sl@0
  2780
	test_KErrNone(r);
sl@0
  2781
	r = buf.Alloc(pool);
sl@0
  2782
	test_KErrNone(r);
sl@0
  2783
	r = buf2.Alloc(pool);
sl@0
  2784
	test_Equal(KErrNoMemory, r);
sl@0
  2785
	TPtr8(buf.Ptr(), buf.Size(), buf.Size()).Fill('!');
sl@0
  2786
	buf.Close();
sl@0
  2787
	pool.Close();
sl@0
  2788
sl@0
  2789
	TShPoolCreateInfo infnpa(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize * KTestPoolSizeInBufs, 1, KTestMinimumAlignmentLog2);
sl@0
  2790
	r = pool.Create(infnpa, KDefaultPoolHandleFlags);
sl@0
  2791
	test_KErrNone(r);
sl@0
  2792
	r = buf.Alloc(pool);
sl@0
  2793
	test_KErrNone(r);
sl@0
  2794
	r = buf2.Alloc(pool);
sl@0
  2795
	test_Equal(KErrNoMemory, r);
sl@0
  2796
	TPtr8(buf.Ptr(), buf.Size(),buf.Size()).Fill('?');
sl@0
  2797
	buf.Close();
sl@0
  2798
	pool.Close();
sl@0
  2799
	}
sl@0
  2800
sl@0
  2801
/*
sl@0
  2802
@SYMTestCaseID				X4
sl@0
  2803
@SYMTestCaseDesc			Negative tests (user/kernel)
sl@0
  2804
@SYMREQ						REQ11423
sl@0
  2805
@SYMTestActions
sl@0
  2806
	API calls with invalid arguments.
sl@0
  2807
@SYMTestExpectedResults
sl@0
  2808
	Appropriate error code returned.
sl@0
  2809
@SYMTestPriority			High
sl@0
  2810
*/
sl@0
  2811
sl@0
  2812
void NegativeTestsUser()
sl@0
  2813
	{
sl@0
  2814
	test.Next(_L("Negative tests (User)"));
sl@0
  2815
	TInt r;
sl@0
  2816
	TInt pagesize;
sl@0
  2817
	TInt ram;
sl@0
  2818
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
  2819
	test_KErrNone(r);
sl@0
  2820
	r = HAL::Get(HAL::EMemoryRAM, ram);
sl@0
  2821
	test_KErrNone(r);
sl@0
  2822
sl@0
  2823
	RShPool pool;
sl@0
  2824
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 0, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2825
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 100, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2826
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 0, 100); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2827
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, KMaxTUint, 10); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2828
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 10, KMaxTUint); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2829
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, KMaxTUint, KMaxTUint); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2830
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 65537, 65536); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2831
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 10, 1 + (1 << (32 - Log2(pagesize)))); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2832
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 4096, 10); r = pool.Create(inf, KDefaultPoolHandleFlags); test_Equal(KErrNone, r); pool.Close(); }
sl@0
  2833
	// XXX The following test will need updating in Phase 2, when exclusive access will be supported
sl@0
  2834
	// (page-aligned-buffer pools only)
sl@0
  2835
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 4096, 10); inf.SetExclusive(); r = pool.Create(inf, KDefaultPoolHandleFlags); test_Equal(KErrNotSupported, r); pool.Close(); }
sl@0
  2836
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 4096, 10, 12); r = pool.Create(inf, KDefaultPoolHandleFlags); test_Equal(KErrNone, r); pool.Close(); }
sl@0
  2837
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 4096, 10, 12); inf.SetExclusive(); r = pool.Create(inf, KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); pool.Close(); }
sl@0
  2838
#ifndef __WINS__
sl@0
  2839
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 128 * pagesize, (ram / (128 * pagesize)) + 1); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrNoMemory, r); }
sl@0
  2840
#endif
sl@0
  2841
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 0, 0, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2842
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 100, 0, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2843
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 0, 100, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2844
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, KMaxTUint, 10, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2845
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, KMaxTUint, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2846
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, KMaxTUint, KMaxTUint, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2847
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 65537, 65536, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2848
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, KMaxTUint); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2849
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, 33); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2850
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 300, 24); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2851
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 65537, 16); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2852
	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10, 10, Log2(pagesize) + 1); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
sl@0
  2853
sl@0
  2854
		{
sl@0
  2855
		TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, *BufferSize, KTestPoolSizeInBufs, 0);
sl@0
  2856
		inf.SetGuardPages();
sl@0
  2857
		r = pool.Create(inf, KDefaultPoolHandleFlags); test_Equal(KErrArgument, r);
sl@0
  2858
		r = inf.SetSizingAttributes(KTestPoolSizeInBufs - 1, 25, 25, 280); test_KErrNone(r); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r);
sl@0
  2859
		// Either grow trigger ratio or grow by ratio == 0 => non-growable pool
sl@0
  2860
		// Such pools must have initial buffers == max buffers
sl@0
  2861
		r = inf.SetSizingAttributes(KTestPoolSizeInBufs * 2, 1, 0, 1); test_Equal(KErrArgument, r); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r);
sl@0
  2862
		r = inf.SetSizingAttributes(KTestPoolSizeInBufs * 2, 1, 0, 0); test_Equal(KErrArgument, r); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r);
sl@0
  2863
		// shrink hysteresis ratio must be > 256
sl@0
  2864
		r = inf.SetSizingAttributes(KTestPoolSizeInBufs - 1, 25, 25, 256); test_Equal(KErrArgument, r); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r);
sl@0
  2865
		// grow ratio must be < 256
sl@0
  2866
		r = inf.SetSizingAttributes(KTestPoolSizeInBufs * 2, 256, 25, 260); test_Equal(KErrArgument, r); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r);
sl@0
  2867
		}
sl@0
  2868
sl@0
  2869
	// Can't have a non-aligned, contiguous pool that grows
sl@0
  2870
	TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 200, 10, 0);
sl@0
  2871
	r = inf.SetSizingAttributes(KTestPoolSizeInBufs * 2, 25, 25, 280);
sl@0
  2872
	test_KErrNone(r);
sl@0
  2873
	}
sl@0
  2874
sl@0
  2875
void NegativeTestsKernel()
sl@0
  2876
	{
sl@0
  2877
	test.Next(_L("Negative tests (Kernel)"));
sl@0
  2878
	TInt r;
sl@0
  2879
	r = Ldd.NegativeTestsKernel();
sl@0
  2880
	test_KErrNone(r);
sl@0
  2881
	}
sl@0
  2882
sl@0
  2883
/*
sl@0
  2884
@SYMTestCaseID				23
sl@0
  2885
@SYMTestCaseDesc			Out of memory testing
sl@0
  2886
@SYMREQ
sl@0
  2887
@SYMTestActions
sl@0
  2888
	TBD
sl@0
  2889
@SYMTestExpectedResults
sl@0
  2890
@SYMTestPriority			High
sl@0
  2891
*/
sl@0
  2892
sl@0
  2893
void OutOfMemory()
sl@0
  2894
	{
sl@0
  2895
	test.Next(_L("Out of memory"));
sl@0
  2896
#ifdef _DEBUG
sl@0
  2897
sl@0
  2898
	
sl@0
  2899
	const TInt KMaxKernelAllocations = 1024;
sl@0
  2900
	TInt i, r;
sl@0
  2901
	RShPool pool;
sl@0
  2902
	TShPoolCreateInfo inf0(TShPoolCreateInfo::EPageAlignedBuffer, *PtrBufSize, 1);
sl@0
  2903
	TShPoolCreateInfo inf1(TShPoolCreateInfo::ENonPageAlignedBuffer, *PtrBufSize, 1, 0);
sl@0
  2904
	r = inf0.SetSizingAttributes(4, 100, 1024, 300);
sl@0
  2905
	test_KErrNone(r);
sl@0
  2906
	r = inf1.SetSizingAttributes(4, 100, 1024, 300);
sl@0
  2907
	test_KErrNone(r);
sl@0
  2908
	
sl@0
  2909
	for(TInt j = 0; j <= 1; j++)
sl@0
  2910
		{
sl@0
  2911
sl@0
  2912
		if(j == 0)
sl@0
  2913
			test.Printf(_L("OOM testing for page-aligned pool\n"));
sl@0
  2914
		else
sl@0
  2915
			test.Printf(_L("OOM testing for non-page-aligned pool\n"));
sl@0
  2916
sl@0
  2917
		r = KErrNoMemory;
sl@0
  2918
sl@0
  2919
		__KHEAP_RESET;
sl@0
  2920
		
sl@0
  2921
		//Create the pool
sl@0
  2922
		for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++)
sl@0
  2923
			{
sl@0
  2924
			__KHEAP_FAILNEXT(i);
sl@0
  2925
			if(j == 0)
sl@0
  2926
				r = pool.Create(inf0,KDefaultPoolHandleFlags);
sl@0
  2927
			else
sl@0
  2928
				r = pool.Create(inf1,KDefaultPoolHandleFlags);
sl@0
  2929
			__KHEAP_RESET;
sl@0
  2930
			}
sl@0
  2931
		test.Printf(_L("Create pool took %d tries\n"),i);
sl@0
  2932
		test_KErrNone(r);
sl@0
  2933
sl@0
  2934
		//Allocate buffers with automatic pool growing enabled
sl@0
  2935
		r = KErrNoMemory;
sl@0
  2936
		RShBuf buf1;
sl@0
  2937
		for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++)
sl@0
  2938
			{
sl@0
  2939
			__KHEAP_FAILNEXT(i);
sl@0
  2940
			if(j == 0)
sl@0
  2941
				r = buf1.Alloc(pool, EShPoolAllocNoMap);
sl@0
  2942
			else
sl@0
  2943
				r = buf1.Alloc(pool);
sl@0
  2944
			__KHEAP_RESET;
sl@0
  2945
			}
sl@0
  2946
		test.Printf(_L("Allocate shared buffer 1 took %d tries\n"),i);	
sl@0
  2947
		test_KErrNone(r);
sl@0
  2948
sl@0
  2949
		// delay to allow the pool to grow
sl@0
  2950
		User::After(20000);
sl@0
  2951
sl@0
  2952
		r = KErrNoMemory;
sl@0
  2953
		RShBuf buf2;
sl@0
  2954
		for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++)
sl@0
  2955
			{
sl@0
  2956
			__KHEAP_FAILNEXT(i);
sl@0
  2957
			if(j == 0)
sl@0
  2958
				r = buf2.Alloc(pool, EShPoolAllocNoMap);
sl@0
  2959
			else
sl@0
  2960
				r = buf2.Alloc(pool);
sl@0
  2961
			__KHEAP_RESET;
sl@0
  2962
			User::After(20000);
sl@0
  2963
			}
sl@0
  2964
		test.Printf(_L("Allocate shared buffer 2 took %d tries\n"),i);	
sl@0
  2965
		test_KErrNone(r);
sl@0
  2966
sl@0
  2967
		// delay to allow the pool to grow again
sl@0
  2968
		User::After(20000);
sl@0
  2969
sl@0
  2970
		r = KErrNoMemory;
sl@0
  2971
		RShBuf buf3;
sl@0
  2972
		for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++)
sl@0
  2973
			{
sl@0
  2974
			__KHEAP_FAILNEXT(i);
sl@0
  2975
			if(j == 0)
sl@0
  2976
				r = buf3.Alloc(pool, EShPoolAllocNoMap);
sl@0
  2977
			else
sl@0
  2978
				r = buf3.Alloc(pool);
sl@0
  2979
			__KHEAP_RESET;
sl@0
  2980
			}
sl@0
  2981
		test.Printf(_L("Allocate shared buffer 3 took %d tries\n"),i);	
sl@0
  2982
		test_KErrNone(r);
sl@0
  2983
sl@0
  2984
		//Map a buffer in page-aligned-pool case
sl@0
  2985
		if(j == 0)
sl@0
  2986
			{
sl@0
  2987
			//Open a one-buffer window
sl@0
  2988
			r = pool.SetBufferWindow(1, ETrue);
sl@0
  2989
			test_KErrNone(r);
sl@0
  2990
sl@0
  2991
			//Map a buffer
sl@0
  2992
			r = KErrNoMemory;
sl@0
  2993
  			for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++)
sl@0
  2994
				{
sl@0
  2995
				buf1.UnMap();
sl@0
  2996
				__KHEAP_FAILNEXT(i);
sl@0
  2997
				r = buf1.Map();
sl@0
  2998
				__KHEAP_RESET;
sl@0
  2999
				}
sl@0
  3000
			test.Printf(_L("Mapping buffer 1 took %d tries\n"),i);	
sl@0
  3001
			test_KErrNone(r);
sl@0
  3002
			}
sl@0
  3003
sl@0
  3004
		//Setup low-space notification
sl@0
  3005
		TRequestStatus low;
sl@0
  3006
		low = KErrNoMemory;
sl@0
  3007
		for (i = 0; i < KMaxKernelAllocations && low != KRequestPending; i++)
sl@0
  3008
			{
sl@0
  3009
			__KHEAP_FAILNEXT(i);
sl@0
  3010
			pool.RequestLowSpaceNotification(1, low);
sl@0
  3011
			__KHEAP_RESET;
sl@0
  3012
			}
sl@0
  3013
		test.Printf(_L("Setting up low-space notification took %d tries\n"),i);
sl@0
  3014
		test_Equal(low.Int(), KRequestPending);
sl@0
  3015
	
sl@0
  3016
		//Setup free-space notification
sl@0
  3017
		TRequestStatus free;
sl@0
  3018
		free = KErrNoMemory;
sl@0
  3019
		for (i = 0; i < KMaxKernelAllocations && free != KRequestPending; i++)
sl@0
  3020
			{
sl@0
  3021
			__KHEAP_FAILNEXT(i);
sl@0
  3022
			pool.RequestFreeSpaceNotification(4, free);
sl@0
  3023
			__KHEAP_RESET;
sl@0
  3024
			}
sl@0
  3025
		test.Printf(_L("Setting up free-space notification took %d tries\n"),i);
sl@0
  3026
		test_Equal(free.Int(), KRequestPending);
sl@0
  3027
		
sl@0
  3028
		//No allocations should occur here
sl@0
  3029
		__KHEAP_FAILNEXT(1);
sl@0
  3030
		if(j == 0)
sl@0
  3031
			{
sl@0
  3032
			//Unmap the buffer
sl@0
  3033
			r = buf1.UnMap();
sl@0
  3034
			}
sl@0
  3035
sl@0
  3036
		//Cancel the notifications
sl@0
  3037
		pool.CancelLowSpaceNotification(low);
sl@0
  3038
		pool.CancelFreeSpaceNotification(free);
sl@0
  3039
	
sl@0
  3040
		//Close the buffers and the pool
sl@0
  3041
		buf1.Close();
sl@0
  3042
		buf2.Close();
sl@0
  3043
		buf3.Close();
sl@0
  3044
		pool.Close();
sl@0
  3045
		__KHEAP_RESET;
sl@0
  3046
sl@0
  3047
		}
sl@0
  3048
sl@0
  3049
	// Allocate kernel-side buffer on Pool 2
sl@0
  3050
	TInt handle = 0;
sl@0
  3051
	RShBuf kbuf;
sl@0
  3052
	r = KErrNoMemory;
sl@0
  3053
	for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++)
sl@0
  3054
		{
sl@0
  3055
		__KHEAP_FAILNEXT(i);
sl@0
  3056
		r = Ldd.AllocateKernelBuffer(1, handle);
sl@0
  3057
		__KHEAP_RESET;
sl@0
  3058
		}
sl@0
  3059
	test.Printf(_L("Allocate kernel buffer took %d tries\n"),i);
sl@0
  3060
	test_KErrNone(r);
sl@0
  3061
     
sl@0
  3062
	__KHEAP_FAILNEXT(1);
sl@0
  3063
	kbuf.SetHandle(handle);
sl@0
  3064
	__KHEAP_RESET;
sl@0
  3065
sl@0
  3066
	r = KErrNoMemory;
sl@0
  3067
	for (i = 0; i < KMaxKernelAllocations && r == KErrNoMemory; i++)
sl@0
  3068
		{
sl@0
  3069
        r = kbuf.UnMap();
sl@0
  3070
		__KHEAP_FAILNEXT(i);
sl@0
  3071
		r = kbuf.Map();
sl@0
  3072
		__KHEAP_RESET;
sl@0
  3073
		}
sl@0
  3074
	test.Printf(_L("Mapping kernel buffer took %d tries\n"),i);
sl@0
  3075
	test_KErrNone(r);
sl@0
  3076
sl@0
  3077
	__KHEAP_FAILNEXT(1);
sl@0
  3078
	r = kbuf.UnMap();
sl@0
  3079
	kbuf.Close();
sl@0
  3080
	__KHEAP_RESET;
sl@0
  3081
sl@0
  3082
sl@0
  3083
#else // _DEBUG
sl@0
  3084
	test.Printf(_L("Debug builds only. Test skipped."));
sl@0
  3085
#endif // _DEBUG
sl@0
  3086
	}
sl@0
  3087
sl@0
  3088
/*
sl@0
  3089
@SYMTestCaseID				22
sl@0
  3090
@SYMTestCaseDesc			Stress testing
sl@0
  3091
@SYMREQ
sl@0
  3092
@SYMTestActions
sl@0
  3093
	TBD
sl@0
  3094
@SYMTestExpectedResults
sl@0
  3095
@SYMTestPriority			Medium
sl@0
  3096
*/
sl@0
  3097
sl@0
  3098
TInt StressThread1(TAny*)
sl@0
  3099
	{
sl@0
  3100
	TInt r;
sl@0
  3101
	TInt pagesize;
sl@0
  3102
	r = HAL::Get(HAL::EMemoryPageSize, pagesize);
sl@0
  3103
	test_KErrNone(r);
sl@0
  3104
sl@0
  3105
	TInt i = 0;
sl@0
  3106
	FOREVER
sl@0
  3107
		{
sl@0
  3108
		RShPool pool;
sl@0
  3109
		if (i % 2)
sl@0
  3110
			{
sl@0
  3111
			TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 1000, 512);
sl@0
  3112
			r = pool.Create(inf,KDefaultPoolHandleFlags);
sl@0
  3113
			if (r)
sl@0
  3114
				{
sl@0
  3115
				RDebug::Printf("Error %d line %d", r, __LINE__);
sl@0
  3116
				break;
sl@0
  3117
				}
sl@0
  3118
sl@0
  3119
			r = pool.SetBufferWindow(-1, ETrue);
sl@0
  3120
			test_KErrNone(r);
sl@0
  3121
sl@0
  3122
			}
sl@0
  3123
		else
sl@0
  3124
			{
sl@0
  3125
			TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 10000, 200, 0);
sl@0
  3126
			r = pool.Create(inf,KDefaultPoolHandleFlags);
sl@0
  3127
			if (r)
sl@0
  3128
				{
sl@0
  3129
				RDebug::Printf("Error %d line %d", r, __LINE__);
sl@0
  3130
				break;
sl@0
  3131
				}
sl@0
  3132
			}
sl@0
  3133
		pool.Close();
sl@0
  3134
		i++;
sl@0
  3135
		if (i % 100 == 0)
sl@0
  3136
			{
sl@0
  3137
			RDebug::Printf("ST1 %d iterations", i);
sl@0
  3138
			}
sl@0
  3139
		}
sl@0
  3140
	return r;
sl@0
  3141
	}
sl@0
  3142
sl@0
  3143
TInt StressThread2(TAny*)
sl@0
  3144
	{
sl@0
  3145
	TInt r = KErrUnknown;
sl@0
  3146
	TShPoolInfo inf1;
sl@0
  3147
	TShPoolInfo inf2;
sl@0
  3148
	P1.GetInfo(inf1);
sl@0
  3149
	P2.GetInfo(inf2);
sl@0
  3150
	TInt j = 0;
sl@0
  3151
	FOREVER
sl@0
  3152
		{
sl@0
  3153
		TUint i;
sl@0
  3154
		RArray<RShBuf> bufarray1;
sl@0
  3155
		RArray<RShBuf> bufarray2;
sl@0
  3156
		for (i = 0; i < inf1.iMaxBufs; i++)
sl@0
  3157
			{
sl@0
  3158
			RShBuf buf;
sl@0
  3159
			r = buf.Alloc(P1);
sl@0
  3160
			if (r)
sl@0
  3161
				{
sl@0
  3162
				RDebug::Printf("Error %d line %d i=%d", r, __LINE__, i);
sl@0
  3163
				break;
sl@0
  3164
				}
sl@0
  3165
			TPtr8(buf.Ptr(), buf.Size(),buf.Size()).Fill('1');
sl@0
  3166
			r = bufarray1.Append(buf);
sl@0
  3167
			if (r)
sl@0
  3168
				{
sl@0
  3169
				buf.Close();
sl@0
  3170
				RDebug::Printf("Error %d line %d i=%d", r, __LINE__, i);
sl@0
  3171
				break;
sl@0
  3172
				}
sl@0
  3173
			}
sl@0
  3174
		for (i = 0; i < inf2.iMaxBufs; i++)
sl@0
  3175
			{
sl@0
  3176
			RShBuf buf;
sl@0
  3177
			r = buf.Alloc(P2);
sl@0
  3178
			if (r)
sl@0
  3179
				{
sl@0
  3180
				RDebug::Printf("Error %d line %d i=%d", r, __LINE__, i);
sl@0
  3181
				break;
sl@0
  3182
				}
sl@0
  3183
			TPtr8(buf.Ptr(), buf.Size(),buf.Size()).Fill('2');
sl@0
  3184
			bufarray2.Append(buf);
sl@0
  3185
			}
sl@0
  3186
		i = 0;
sl@0
  3187
		while (bufarray1.Count())
sl@0
  3188
			{
sl@0
  3189
			bufarray1[0].Close();
sl@0
  3190
			bufarray1.Remove(0);
sl@0
  3191
			i++;
sl@0
  3192
			}
sl@0
  3193
sl@0
  3194
		while (bufarray2.Count())
sl@0
  3195
			{
sl@0
  3196
			bufarray2[0].Close();
sl@0
  3197
			bufarray2.Remove(0);
sl@0
  3198
			}
sl@0
  3199
		bufarray1.Close();
sl@0
  3200
		bufarray2.Close();
sl@0
  3201
		if (r)
sl@0
  3202
			{
sl@0
  3203
			break;
sl@0
  3204
			}
sl@0
  3205
		j++;
sl@0
  3206
		if (j % 10 == 0)
sl@0
  3207
			{
sl@0
  3208
			RDebug::Printf("ST2 %d iterations", j);
sl@0
  3209
			}
sl@0
  3210
		}
sl@0
  3211
	return r;
sl@0
  3212
	}
sl@0
  3213
sl@0
  3214
void StressTesting(TInt aSecs)
sl@0
  3215
	{
sl@0
  3216
	test.Next(_L("Stress testing"));
sl@0
  3217
	TInt r;
sl@0
  3218
sl@0
  3219
	test.Start(_L("Create pools"));
sl@0
  3220
	TShPoolCreateInfo inf1(TShPoolCreateInfo::ENonPageAlignedBuffer, 2000, 500, 11);
sl@0
  3221
	r = P1.Create(inf1,KDefaultPoolHandleFlags);
sl@0
  3222
	test_KErrNone(r);
sl@0
  3223
	TInt handle;
sl@0
  3224
	TShPoolCreateInfo inf2(TShPoolCreateInfo::EPageAlignedBuffer, 5000, 150);
sl@0
  3225
	r = Ldd.OpenKernelPool(inf2, handle);
sl@0
  3226
	test_KErrNone(r);
sl@0
  3227
	P2.SetHandle(handle);
sl@0
  3228
sl@0
  3229
	r = P2.SetBufferWindow(-1, ETrue);
sl@0
  3230
	test_KErrNone(r);
sl@0
  3231
sl@0
  3232
	test.Next(_L("Create threads"));
sl@0
  3233
	RThread t1;
sl@0
  3234
	r = t1.Create(_L("THREAD1"), StressThread1, KDefaultStackSize, KMinHeapSize, KMinHeapSize, NULL);
sl@0
  3235
	test_KErrNone(r);
sl@0
  3236
	RThread t2;
sl@0
  3237
	r = t2.Create(_L("THREAD2"), StressThread2, KDefaultStackSize*2, KMinHeapSize, 1 << 20, NULL);
sl@0
  3238
	test_KErrNone(r);
sl@0
  3239
	test.Next(_L("Start threads"));
sl@0
  3240
	test.Printf(_L("Wait for %d seconds\n"), aSecs);
sl@0
  3241
	RThread().SetPriority(EPriorityMore);
sl@0
  3242
	TRequestStatus t1rs;
sl@0
  3243
	TRequestStatus t2rs;
sl@0
  3244
	t1.Logon(t1rs);
sl@0
  3245
	t2.Logon(t2rs);
sl@0
  3246
	t1.Resume();
sl@0
  3247
	t2.Resume();
sl@0
  3248
	User::After(aSecs * 1000000);
sl@0
  3249
sl@0
  3250
	test.Next(_L("Kill threads"));
sl@0
  3251
	t1.Kill(KErrNone);
sl@0
  3252
	t2.Kill(KErrNone);
sl@0
  3253
sl@0
  3254
	// wait for threads to actually die
sl@0
  3255
	User::WaitForRequest(t1rs);
sl@0
  3256
	User::WaitForRequest(t2rs);
sl@0
  3257
sl@0
  3258
	t1.Close();
sl@0
  3259
	t2.Close();
sl@0
  3260
	RThread().SetPriority(EPriorityNormal);
sl@0
  3261
sl@0
  3262
	test.Next(_L("Close pools"));
sl@0
  3263
	P1.Close();
sl@0
  3264
	r = Ldd.CloseKernelPool();
sl@0
  3265
	test_KErrNone(r);
sl@0
  3266
	P2.Close();
sl@0
  3267
	test.End();
sl@0
  3268
	}
sl@0
  3269
sl@0
  3270
/*
sl@0
  3271
@SYMTestCaseID
sl@0
  3272
@SYMTestCaseDesc
sl@0
  3273
@SYMREQ
sl@0
  3274
@SYMTestActions
sl@0
  3275
@SYMTestExpectedResults
sl@0
  3276
@SYMTestPriority
sl@0
  3277
*/
sl@0
  3278
sl@0
  3279
void NoDeallocation()
sl@0
  3280
	{
sl@0
  3281
	test.Next(_L("No deallocation"));
sl@0
  3282
	TInt r;
sl@0
  3283
	TBuf<10> command;
sl@0
  3284
	command.Format(_L("%S %d"), &KTestSlave, ETestSlaveNoDeallocation);
sl@0
  3285
	RProcess p;
sl@0
  3286
	r = p.Create(RProcess().FileName(), command);
sl@0
  3287
	test_KErrNone(r);
sl@0
  3288
	TRequestStatus rs;
sl@0
  3289
	p.Logon(rs);
sl@0
  3290
	p.Resume();
sl@0
  3291
	User::WaitForRequest(rs);
sl@0
  3292
sl@0
  3293
	// wait for memory to be freed
sl@0
  3294
	r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, (TAny*)5000, 0);
sl@0
  3295
	test_KErrNone(r);
sl@0
  3296
sl@0
  3297
	__KHEAP_MARKEND;
sl@0
  3298
	test_KErrNone(rs.Int());
sl@0
  3299
	test_Equal(EExitKill, p.ExitType());
sl@0
  3300
	test_KErrNone(p.ExitReason());
sl@0
  3301
	p.Close();
sl@0
  3302
	}
sl@0
  3303
sl@0
  3304
TInt SlaveNoDeallocation()
sl@0
  3305
	{
sl@0
  3306
	__KHEAP_MARK;
sl@0
  3307
	TInt r;
sl@0
  3308
	RShPool pool;
sl@0
  3309
	TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *BufferSize, KTestPoolSizeInBufs);
sl@0
  3310
	r = pool.Create(inf,KDefaultPoolHandleFlags);
sl@0
  3311
	test_KErrNone(r);
sl@0
  3312
sl@0
  3313
	pool.SetBufferWindow(-1, ETrue);
sl@0
  3314
	test_KErrNone(r);
sl@0
  3315
sl@0
  3316
	if (!r)
sl@0
  3317
		{
sl@0
  3318
		RShBuf buf;
sl@0
  3319
		r = buf.Alloc(pool);
sl@0
  3320
		}
sl@0
  3321
	return r;
sl@0
  3322
	}
sl@0
  3323
sl@0
  3324
TInt E32Main()
sl@0
  3325
	{
sl@0
  3326
	__UHEAP_MARK;
sl@0
  3327
sl@0
  3328
	// Parse command line for slave processes
sl@0
  3329
	TInt r = KErrArgument;
sl@0
  3330
	TBuf<KMaxFullName> cmd;
sl@0
  3331
	User::CommandLine(cmd);
sl@0
  3332
	TLex lex(cmd);
sl@0
  3333
	if (lex.NextToken() == KTestSlave)
sl@0
  3334
		{
sl@0
  3335
		TInt function;
sl@0
  3336
		TLex functionlex(lex.NextToken());
sl@0
  3337
		functionlex.Val(function);
sl@0
  3338
		switch (function)
sl@0
  3339
			{
sl@0
  3340
			case ETestSlaveNoDeallocation:
sl@0
  3341
				r = SlaveNoDeallocation();
sl@0
  3342
				break;
sl@0
  3343
			}
sl@0
  3344
		__UHEAP_MARKEND;
sl@0
  3345
		return r;
sl@0
  3346
		}
sl@0
  3347
	// Test starts here
sl@0
  3348
	test.Title();
sl@0
  3349
sl@0
  3350
	test.Start(_L("Check for Shared Buffers availability"));
sl@0
  3351
	RShPool pool;
sl@0
  3352
	TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, *BufferSize, KTestPoolSizeInBufs);
sl@0
  3353
	r = pool.Create(inf,KDefaultPoolHandleFlags);
sl@0
  3354
	if (r == KErrNotSupported)
sl@0
  3355
		{
sl@0
  3356
		test.Printf(_L("Not supported by this memory model.\n"));
sl@0
  3357
		}
sl@0
  3358
	else
sl@0
  3359
		{
sl@0
  3360
		test_KErrNone(r);
sl@0
  3361
		pool.Close();
sl@0
  3362
sl@0
  3363
		test.Next(_L("No device driver"));
sl@0
  3364
		test.Start(_L("Start test loop"));
sl@0
  3365
		for (PtrBufSize = BufferSize; *PtrBufSize != 0; PtrBufSize++)
sl@0
  3366
			{
sl@0
  3367
			TBuf<30> title;
sl@0
  3368
			title.Format(_L("Buffer size = %d bytes"), *PtrBufSize);
sl@0
  3369
			test.Next(title);
sl@0
  3370
			test.Start(_L("New test iteration"));
sl@0
  3371
			BufferAlignmentUser();
sl@0
  3372
			BufferMapping();
sl@0
  3373
			BufferWindow();
sl@0
  3374
			GuardPages();
sl@0
  3375
			PoolGrowingUser();
sl@0
  3376
			SingleBufferPool();
sl@0
  3377
			test.End();
sl@0
  3378
			}
sl@0
  3379
		test.End();
sl@0
  3380
		test.Next(_L("Load Device Driver"));
sl@0
  3381
		LoadDeviceDrivers();
sl@0
  3382
sl@0
  3383
		#ifdef TEST_CLIENT_THREAD
sl@0
  3384
		test.Next(_L("Device driver in client thread"));
sl@0
  3385
		r = Ldd.Open(0);
sl@0
  3386
		#else
sl@0
  3387
		test.Next(_L("Device driver in own thread"));
sl@0
  3388
		r = Ldd.Open(1);
sl@0
  3389
		#endif
sl@0
  3390
sl@0
  3391
		test_KErrNone(r);
sl@0
  3392
sl@0
  3393
		test.Start(_L("Start test loop"));
sl@0
  3394
		for (PtrBufSize = BufferSize; *PtrBufSize != 0; PtrBufSize++)
sl@0
  3395
			{
sl@0
  3396
			TBuf<30> title;
sl@0
  3397
			title.Format(_L("Buffer size = %d bytes"), *PtrBufSize);
sl@0
  3398
			test.Next(title);
sl@0
  3399
			test.Start(_L("New test iteration"));
sl@0
  3400
			CreateUserPool(ETestNonPageAligned);
sl@0
  3401
			CreateKernelPool(ETestNonPageAligned);
sl@0
  3402
			AllocateUserBuffer();
sl@0
  3403
			AllocateKernelBuffer();
sl@0
  3404
			AllocateUserMax(P1);
sl@0
  3405
			AllocateUserMax(P2);
sl@0
  3406
			AllocateKernelMax();
sl@0
  3407
			BufferAlignmentKernel();
sl@0
  3408
			CreateKernelPoolPhysAddr();
sl@0
  3409
			NotificationRequests(P1);
sl@0
  3410
			NotificationRequests(P2);
sl@0
  3411
			CancelNotificationRequests(P1);
sl@0
  3412
			CancelNotificationRequests(P2);
sl@0
  3413
			ShBufPin();
sl@0
  3414
			CloseKernelPool();
sl@0
  3415
			CloseUserPool();
sl@0
  3416
			ContiguousPoolKernel();
sl@0
  3417
			CreateUserPool(ETestPageAligned);
sl@0
  3418
			CreateKernelPool(ETestPageAligned);
sl@0
  3419
			OutOfMemory();
sl@0
  3420
			AllocateUserBuffer();
sl@0
  3421
			AllocateKernelBuffer();
sl@0
  3422
			AllocateUserMax(P1);
sl@0
  3423
			AllocateUserMax(P2);
sl@0
  3424
			AllocateKernelMax();
sl@0
  3425
			NotificationRequests(P1);
sl@0
  3426
			NotificationRequests(P2);
sl@0
  3427
			CloseUserPool();
sl@0
  3428
			CloseKernelPool();
sl@0
  3429
			CreateUserPool(ETestPageAlignedGrowing);
sl@0
  3430
			CreateKernelPool(ETestPageAlignedGrowing);
sl@0
  3431
			OutOfMemory();
sl@0
  3432
			AllocateKernelMax();
sl@0
  3433
			AllocateUserMax(P1);
sl@0
  3434
			AllocateUserMax(P2);
sl@0
  3435
			CloseUserPool();
sl@0
  3436
			CloseKernelPool();
sl@0
  3437
			test.End();
sl@0
  3438
			}
sl@0
  3439
		NegativeTestsKernel();
sl@0
  3440
		StressTesting(5);
sl@0
  3441
		test.End();
sl@0
  3442
		Ldd.Close();
sl@0
  3443
sl@0
  3444
		NegativeTestsUser();
sl@0
  3445
		NoDeallocation();
sl@0
  3446
sl@0
  3447
		test.Next(_L("Unload Device Drivers"));
sl@0
  3448
		FreeDeviceDrivers();
sl@0
  3449
		}
sl@0
  3450
	test.End();
sl@0
  3451
	test.Close();
sl@0
  3452
sl@0
  3453
	__UHEAP_MARKEND;
sl@0
  3454
	return KErrNone;
sl@0
  3455
	}