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