os/kernelhwsrv/kerneltest/e32test/prime/t_semutx.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32test\prime\t_semutx.cpp
sl@0
    15
// Tests the RSemaphore, RMutex and RCriticalSection classes
sl@0
    16
// Overview:
sl@0
    17
// Tests the RSemaphore, RMutex and RCriticalSection classes
sl@0
    18
// API Information:
sl@0
    19
// RSemaphore, RMutex, RCriticalSection
sl@0
    20
// Details:
sl@0
    21
// - Test RSemaphore and RMutex with the producer/consumer scenario.
sl@0
    22
// Create two threads, use signal and wait to coordinate the
sl@0
    23
// threads. Verify results are as expected.
sl@0
    24
// - Calculate the time required to create, resume and close a thread.
sl@0
    25
// - Test RSemaphore::Wait(timeout) in a variety ways and timeout 
sl@0
    26
// values. Verify results are as expected.
sl@0
    27
// - Test RMutex via two threads which write to an array. The writing
sl@0
    28
// and updating of the index is wrapped within a mutex pair. Verify 
sl@0
    29
// results are as expected.
sl@0
    30
// - Test RCriticalSection via two threads which write to an array. The 
sl@0
    31
// writing and updating of the index is wrapped within a critical section
sl@0
    32
// pair. Verify results are as expected.
sl@0
    33
// Platforms/Drives/Compatibility:
sl@0
    34
// All.
sl@0
    35
// Assumptions/Requirement/Pre-requisites:
sl@0
    36
// Failures and causes:
sl@0
    37
// Base Port information:
sl@0
    38
// 
sl@0
    39
//
sl@0
    40
sl@0
    41
#include <e32test.h>
sl@0
    42
sl@0
    43
const TInt KMaxBufferSize=10;
sl@0
    44
const TInt KMaxArraySize=10;
sl@0
    45
const TInt KNumProducerItems=100;
sl@0
    46
sl@0
    47
enum {EThread1ID=1,EThread2ID};
sl@0
    48
sl@0
    49
RTest test(_L("T_SEMUTX"));
sl@0
    50
RMutex mutex;
sl@0
    51
RCriticalSection criticalSn;	
sl@0
    52
TInt thread1Count,thread2Count;
sl@0
    53
TInt arrayIndex;
sl@0
    54
TInt array[KMaxArraySize];  
sl@0
    55
TInt consumerArray[KNumProducerItems];
sl@0
    56
RSemaphore slotAvailable,itemAvailable;  
sl@0
    57
			 
sl@0
    58
class CStack
sl@0
    59
	{
sl@0
    60
public:	   
sl@0
    61
	CStack() {iCount=0;};
sl@0
    62
	void Push(TInt aItem) {iStack[iCount++]=aItem;};
sl@0
    63
	TInt Pop(void) {return(iStack[--iCount]);};
sl@0
    64
private:
sl@0
    65
	TInt iStack[KMaxBufferSize];
sl@0
    66
	TInt iCount;
sl@0
    67
	};
sl@0
    68
CStack stack;
sl@0
    69
sl@0
    70
sl@0
    71
TInt Producer(TAny*)
sl@0
    72
	{
sl@0
    73
	for(TInt ii=0;ii<KNumProducerItems;ii++)
sl@0
    74
		{
sl@0
    75
		slotAvailable.Wait();
sl@0
    76
		mutex.Wait();
sl@0
    77
		stack.Push(ii);
sl@0
    78
		mutex.Signal();
sl@0
    79
		itemAvailable.Signal();
sl@0
    80
		}
sl@0
    81
	return(KErrNone);
sl@0
    82
	}
sl@0
    83
sl@0
    84
TInt Consumer(TAny*)
sl@0
    85
	{
sl@0
    86
	TInt item;
sl@0
    87
	for(TInt ii=0;ii<KNumProducerItems;ii++)
sl@0
    88
		{
sl@0
    89
		itemAvailable.Wait();
sl@0
    90
		mutex.Wait();
sl@0
    91
		item=stack.Pop();
sl@0
    92
		mutex.Signal();
sl@0
    93
		slotAvailable.Signal();
sl@0
    94
		consumerArray[item]=item;
sl@0
    95
		}
sl@0
    96
	return(KErrNone);
sl@0
    97
	}
sl@0
    98
sl@0
    99
void BusyWait(TInt aMicroseconds)
sl@0
   100
	{
sl@0
   101
	TTime begin;
sl@0
   102
	begin.HomeTime();
sl@0
   103
	FOREVER
sl@0
   104
		{
sl@0
   105
		TTime now;
sl@0
   106
		now.HomeTime();
sl@0
   107
		TTimeIntervalMicroSeconds iv=now.MicroSecondsFrom(begin);
sl@0
   108
		if (iv.Int64()>=TInt64(aMicroseconds))
sl@0
   109
			return;
sl@0
   110
		}
sl@0
   111
	}
sl@0
   112
sl@0
   113
TInt MutexThreadEntryPoint1(TAny*)
sl@0
   114
//
sl@0
   115
// Mutex test thread 1
sl@0
   116
//
sl@0
   117
	{	
sl@0
   118
sl@0
   119
	thread1Count=0;
sl@0
   120
	TBool running=ETrue;
sl@0
   121
	do
sl@0
   122
		{
sl@0
   123
		mutex.Wait();
sl@0
   124
		BusyWait(100000);
sl@0
   125
		if (arrayIndex<KMaxArraySize)
sl@0
   126
			{
sl@0
   127
			array[arrayIndex++]=EThread1ID;
sl@0
   128
			thread1Count++;
sl@0
   129
			}
sl@0
   130
		else
sl@0
   131
			running=EFalse;
sl@0
   132
		mutex.Signal();
sl@0
   133
		} while (running);
sl@0
   134
	return(KErrNone);
sl@0
   135
	}
sl@0
   136
sl@0
   137
TInt MutexThreadEntryPoint2(TAny*)
sl@0
   138
//
sl@0
   139
// Mutex test thread 2
sl@0
   140
//
sl@0
   141
	{
sl@0
   142
sl@0
   143
	thread2Count=0;
sl@0
   144
	TBool running=ETrue;
sl@0
   145
	do
sl@0
   146
		{
sl@0
   147
		mutex.Wait();
sl@0
   148
		BusyWait(200000);
sl@0
   149
		if (arrayIndex<KMaxArraySize)
sl@0
   150
			{
sl@0
   151
			array[arrayIndex++]=EThread2ID;
sl@0
   152
			thread2Count++;
sl@0
   153
			}
sl@0
   154
		else
sl@0
   155
			running=EFalse;
sl@0
   156
		mutex.Signal();
sl@0
   157
		} while (running);
sl@0
   158
	return(KErrNone);
sl@0
   159
	}
sl@0
   160
sl@0
   161
TInt CriticalSnThreadEntryPoint1(TAny*)
sl@0
   162
//
sl@0
   163
// Critical Section test thread 1
sl@0
   164
//
sl@0
   165
	{	
sl@0
   166
sl@0
   167
	thread1Count=0;
sl@0
   168
	TBool running=ETrue;
sl@0
   169
	do
sl@0
   170
		{
sl@0
   171
		criticalSn.Wait();
sl@0
   172
		User::After(100000);
sl@0
   173
		if (arrayIndex<KMaxArraySize)
sl@0
   174
			{
sl@0
   175
			array[arrayIndex++]=EThread1ID;
sl@0
   176
			thread1Count++;
sl@0
   177
			}
sl@0
   178
		else
sl@0
   179
			running=EFalse;
sl@0
   180
		criticalSn.Signal();
sl@0
   181
		} while (running);
sl@0
   182
	return(KErrNone);
sl@0
   183
	}
sl@0
   184
sl@0
   185
TInt CriticalSnThreadEntryPoint2(TAny*)
sl@0
   186
//
sl@0
   187
// Critical Section test thread 2
sl@0
   188
//
sl@0
   189
	{
sl@0
   190
sl@0
   191
	thread2Count=0;
sl@0
   192
	TBool running=ETrue;
sl@0
   193
	do
sl@0
   194
		{
sl@0
   195
		criticalSn.Wait();
sl@0
   196
		User::After(200000);
sl@0
   197
		if (arrayIndex<KMaxArraySize)
sl@0
   198
			{
sl@0
   199
			array[arrayIndex++]=EThread2ID;
sl@0
   200
			thread2Count++;
sl@0
   201
			}
sl@0
   202
		else
sl@0
   203
			running=EFalse;
sl@0
   204
		criticalSn.Signal();
sl@0
   205
		} while (running);
sl@0
   206
	return(KErrNone);
sl@0
   207
	}
sl@0
   208
sl@0
   209
struct SWaitSem
sl@0
   210
	{
sl@0
   211
	RSemaphore iSem;
sl@0
   212
	TInt iTimeout;
sl@0
   213
	};
sl@0
   214
sl@0
   215
TInt WaitSemThread(TAny* a)
sl@0
   216
	{
sl@0
   217
	SWaitSem& ws = *(SWaitSem*)a;
sl@0
   218
	return ws.iSem.Wait(ws.iTimeout);
sl@0
   219
	}
sl@0
   220
sl@0
   221
void StartWaitSemThread(RThread& aT, SWaitSem& aW, TThreadPriority aP=EPriorityLess)
sl@0
   222
	{
sl@0
   223
	TInt r = aT.Create(KNullDesC, &WaitSemThread, 0x1000, 0x1000, 0x1000, &aW);
sl@0
   224
	test(r==KErrNone);
sl@0
   225
	aT.SetPriority(aP);
sl@0
   226
	aT.Resume();
sl@0
   227
	}
sl@0
   228
sl@0
   229
void WaitForWaitSemThread(RThread& aT, TInt aResult)
sl@0
   230
	{
sl@0
   231
	TRequestStatus s;
sl@0
   232
	aT.Logon(s);
sl@0
   233
	User::WaitForRequest(s);
sl@0
   234
	test(aT.ExitType()==EExitKill);
sl@0
   235
	test(aT.ExitReason()==aResult);
sl@0
   236
	test(s.Int()==aResult);
sl@0
   237
	CLOSE_AND_WAIT(aT);
sl@0
   238
	}
sl@0
   239
sl@0
   240
TInt DummyThread(TAny*)
sl@0
   241
	{
sl@0
   242
	return 0;
sl@0
   243
	}
sl@0
   244
sl@0
   245
void TestSemaphore2()
sl@0
   246
	{
sl@0
   247
	test.Start(_L("Test semaphore wait with timeout"));
sl@0
   248
	SWaitSem ws;
sl@0
   249
	RThread t;
sl@0
   250
	TTime initial;
sl@0
   251
	TTime final;
sl@0
   252
	TInt elapsed=0;
sl@0
   253
	TInt r = ws.iSem.CreateLocal(0);
sl@0
   254
	test(r==KErrNone);
sl@0
   255
sl@0
   256
	RThread().SetPriority(EPriorityAbsoluteVeryLow);
sl@0
   257
	TInt threadcount=0;
sl@0
   258
	initial.HomeTime();
sl@0
   259
	while (elapsed<1000000)
sl@0
   260
		{
sl@0
   261
		r = t.Create(KNullDesC, &DummyThread, 0x1000, NULL, NULL);
sl@0
   262
		test(r==KErrNone);
sl@0
   263
		t.SetPriority(EPriorityMore);
sl@0
   264
		t.Resume();
sl@0
   265
		t.Close();
sl@0
   266
		++threadcount;
sl@0
   267
		final.HomeTime();
sl@0
   268
		elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   269
		}
sl@0
   270
	RThread().SetPriority(EPriorityNormal);
sl@0
   271
	test.Printf(_L("%d threads in 1 sec\n"),threadcount);
sl@0
   272
	TInt overhead = 1000000/threadcount;
sl@0
   273
	test.Printf(_L("overhead = %dus\n"),overhead);
sl@0
   274
sl@0
   275
	ws.iTimeout=1000000;
sl@0
   276
	initial.HomeTime();
sl@0
   277
	StartWaitSemThread(t, ws);
sl@0
   278
	WaitForWaitSemThread(t, KErrTimedOut);
sl@0
   279
	final.HomeTime();
sl@0
   280
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   281
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   282
	test(elapsed>=900000+overhead && elapsed<1500000+overhead);
sl@0
   283
sl@0
   284
	ws.iTimeout=-1;
sl@0
   285
	initial.HomeTime();
sl@0
   286
	StartWaitSemThread(t, ws);
sl@0
   287
	WaitForWaitSemThread(t, KErrArgument);
sl@0
   288
	final.HomeTime();
sl@0
   289
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   290
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   291
sl@0
   292
	ws.iTimeout=2000000;
sl@0
   293
	initial.HomeTime();
sl@0
   294
	StartWaitSemThread(t, ws);
sl@0
   295
	User::After(1000000);
sl@0
   296
	ws.iSem.Signal();
sl@0
   297
	WaitForWaitSemThread(t, KErrNone);
sl@0
   298
	final.HomeTime();
sl@0
   299
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   300
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   301
	test(elapsed>=900000+overhead && elapsed<1500000+overhead);
sl@0
   302
sl@0
   303
	ws.iTimeout=100000;
sl@0
   304
	StartWaitSemThread(t, ws, EPriorityMore);
sl@0
   305
	t.Suspend();
sl@0
   306
	ws.iSem.Signal();
sl@0
   307
	User::After(200000);
sl@0
   308
	t.Resume();
sl@0
   309
	WaitForWaitSemThread(t, KErrTimedOut);
sl@0
   310
	test(ws.iSem.Wait(1)==KErrNone);
sl@0
   311
sl@0
   312
	ws.iTimeout=100000;
sl@0
   313
	StartWaitSemThread(t, ws, EPriorityMore);
sl@0
   314
	t.Suspend();
sl@0
   315
	ws.iSem.Signal();
sl@0
   316
	User::After(50000);
sl@0
   317
	t.Resume();
sl@0
   318
	WaitForWaitSemThread(t, KErrNone);
sl@0
   319
	test(ws.iSem.Wait(1)==KErrTimedOut);
sl@0
   320
sl@0
   321
	RThread t2;
sl@0
   322
	ws.iTimeout=100000;
sl@0
   323
	StartWaitSemThread(t, ws, EPriorityMuchMore);
sl@0
   324
	StartWaitSemThread(t2, ws, EPriorityMore);
sl@0
   325
	t.Suspend();
sl@0
   326
	ws.iSem.Signal();
sl@0
   327
	test(t2.ExitType()==EExitKill);
sl@0
   328
	test(t.ExitType()==EExitPending);
sl@0
   329
	t.Resume();
sl@0
   330
	WaitForWaitSemThread(t, KErrTimedOut);
sl@0
   331
	WaitForWaitSemThread(t2, KErrNone);
sl@0
   332
	test(ws.iSem.Wait(1)==KErrTimedOut);
sl@0
   333
sl@0
   334
	ws.iTimeout=1000000;
sl@0
   335
	initial.HomeTime();
sl@0
   336
	StartWaitSemThread(t2, ws, EPriorityMore);
sl@0
   337
	StartWaitSemThread(t, ws, EPriorityMuchMore);
sl@0
   338
	ws.iSem.Signal();
sl@0
   339
	WaitForWaitSemThread(t, KErrNone);
sl@0
   340
	final.HomeTime();
sl@0
   341
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   342
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   343
	WaitForWaitSemThread(t2, KErrTimedOut);
sl@0
   344
	final.HomeTime();
sl@0
   345
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   346
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   347
	test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
sl@0
   348
sl@0
   349
	ws.iTimeout=1000000;
sl@0
   350
	initial.HomeTime();
sl@0
   351
	StartWaitSemThread(t2, ws, EPriorityMore);
sl@0
   352
	StartWaitSemThread(t, ws, EPriorityMuchMore);
sl@0
   353
	WaitForWaitSemThread(t, KErrTimedOut);
sl@0
   354
	final.HomeTime();
sl@0
   355
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   356
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   357
	WaitForWaitSemThread(t2, KErrTimedOut);
sl@0
   358
	final.HomeTime();
sl@0
   359
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   360
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   361
	test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
sl@0
   362
sl@0
   363
	ws.iTimeout=1000000;
sl@0
   364
	initial.HomeTime();
sl@0
   365
	StartWaitSemThread(t2, ws, EPriorityMore);
sl@0
   366
	StartWaitSemThread(t, ws, EPriorityMuchMore);
sl@0
   367
	t.Kill(299792458);
sl@0
   368
	WaitForWaitSemThread(t2, KErrTimedOut);
sl@0
   369
	WaitForWaitSemThread(t, 299792458);
sl@0
   370
	final.HomeTime();
sl@0
   371
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   372
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   373
	test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
sl@0
   374
sl@0
   375
	ws.iTimeout=1000000;
sl@0
   376
	initial.HomeTime();
sl@0
   377
	StartWaitSemThread(t, ws, EPriorityMore);
sl@0
   378
	StartWaitSemThread(t2, ws, EPriorityMuchMore);
sl@0
   379
	test(t.ExitType()==EExitPending);
sl@0
   380
	test(t2.ExitType()==EExitPending);
sl@0
   381
	ws.iSem.Close();
sl@0
   382
	test(t.ExitType()==EExitKill);
sl@0
   383
	test(t2.ExitType()==EExitKill);
sl@0
   384
	WaitForWaitSemThread(t2, KErrGeneral);
sl@0
   385
	WaitForWaitSemThread(t, KErrGeneral);
sl@0
   386
	final.HomeTime();
sl@0
   387
	elapsed = I64INT(final.Int64()-initial.Int64());
sl@0
   388
	test.Printf(_L("Time taken = %dus\n"), elapsed);
sl@0
   389
	test(elapsed<=50000+3*overhead);
sl@0
   390
sl@0
   391
	test.End();
sl@0
   392
	}
sl@0
   393
sl@0
   394
void TestSemaphore()
sl@0
   395
	{
sl@0
   396
/*********** TO DO ************/
sl@0
   397
// Check it panics if the count <0
sl@0
   398
sl@0
   399
	test.Start(_L("Create"));
sl@0
   400
	RSemaphore semaphore;
sl@0
   401
	RThread thread1, thread2;
sl@0
   402
sl@0
   403
	semaphore.CreateLocal(0); 	// creates a DPlatSemaphore but casts it to a pointer to a DSemaphore
sl@0
   404
								// sets semaphore count to the value of the parameter, 
sl@0
   405
								// adds object to the K::Semaphores container, sets iHandle
sl@0
   406
								// Local sets DSemaphore.iName to NULL & iOwner to Kern::CurrentProcess()
sl@0
   407
								// Global sets iName to that passed and iOwner to NULL
sl@0
   408
								// Adds a record into CObjectIx containing a pointer to the semaphore object
sl@0
   409
/*	test.Next(_L("Find"));
sl@0
   410
	fullName=semaphore.FullName();	
sl@0
   411
	find.Find(fullName);	// sets iMatch to fullName	(misleadingly named method as it doesn't find anything)
sl@0
   412
	test(find.Next(fullName)== KErrNone);	
sl@0
   413
*/
sl@0
   414
	test.Next(_L("Producer/Consumer scenario"));
sl@0
   415
	// Test Rsemaphore with the producer/consumer scenario	RThread thread1, thread2;
sl@0
   416
	TRequestStatus stat1, stat2;
sl@0
   417
	test(mutex.CreateLocal()==KErrNone);
sl@0
   418
	test(slotAvailable.CreateLocal(KMaxBufferSize)==KErrNone);
sl@0
   419
	test(itemAvailable.CreateLocal(0)==KErrNone);
sl@0
   420
	test(thread1.Create(_L("Thread1"),Producer,KDefaultStackSize,0x200,0x200,NULL)==KErrNone);
sl@0
   421
	test(thread2.Create(_L("Thread2"),Consumer,KDefaultStackSize,0x200,0x200,NULL)==KErrNone);
sl@0
   422
	thread1.Logon(stat1);
sl@0
   423
	thread2.Logon(stat2);
sl@0
   424
	test(stat1==KRequestPending);
sl@0
   425
	test(stat2==KRequestPending);
sl@0
   426
	thread1.Resume(); 
sl@0
   427
	thread2.Resume();
sl@0
   428
	User::WaitForRequest(stat1);
sl@0
   429
	User::WaitForRequest(stat2);
sl@0
   430
	test(stat1==KErrNone);
sl@0
   431
	test(stat2==KErrNone);
sl@0
   432
	for(TInt jj=0;jj<KNumProducerItems;jj++)
sl@0
   433
		test(consumerArray[jj]==jj);		
sl@0
   434
	
sl@0
   435
	test.Next(_L("Close"));
sl@0
   436
	mutex.Close();
sl@0
   437
	CLOSE_AND_WAIT(thread1);
sl@0
   438
	CLOSE_AND_WAIT(thread2);
sl@0
   439
	test.End();
sl@0
   440
	}
sl@0
   441
sl@0
   442
void TestMutex2()
sl@0
   443
	{
sl@0
   444
	RMutex m;
sl@0
   445
	test.Start(_L("Create"));
sl@0
   446
	test(m.CreateLocal()==KErrNone);
sl@0
   447
sl@0
   448
	// Test RMutex::IsHeld()
sl@0
   449
	test.Next(_L("IsHeld ?"));
sl@0
   450
	test(!m.IsHeld());
sl@0
   451
	test.Next(_L("Wait"));
sl@0
   452
	m.Wait();
sl@0
   453
	test.Next(_L("IsHeld ?"));
sl@0
   454
	test(m.IsHeld());
sl@0
   455
	test.Next(_L("Signal"));
sl@0
   456
	m.Signal();
sl@0
   457
	test.Next(_L("IsHeld ?"));
sl@0
   458
	test(!m.IsHeld());
sl@0
   459
sl@0
   460
	test.End();
sl@0
   461
	}
sl@0
   462
sl@0
   463
void TestMutex()
sl@0
   464
	{
sl@0
   465
	test.Start(_L("Create"));
sl@0
   466
	test(mutex.CreateLocal()==KErrNone);
sl@0
   467
	
sl@0
   468
	test.Next(_L("Threads writing to arrays test"));
sl@0
   469
//
sl@0
   470
// Create two threads which write to two arrays. The arrays and indexs
sl@0
   471
// are global and each thread writes an identifier to the arrays. For
sl@0
   472
// one array the writing and updating of the index is wrapped in a mutex
sl@0
   473
// pair. The other array is a control and is not wrapaped within mutex.
sl@0
   474
// Each thread records the number of instances it "thinks" it wrote to
sl@0
   475
// each array. For the mutex controlled array the actual instances
sl@0
   476
// written to the array should always be the same as the threads think.
sl@0
   477
//
sl@0
   478
	arrayIndex=0;
sl@0
   479
	RThread thread1,thread2;	
sl@0
   480
	test(thread1.Create(_L("Thread1"),MutexThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);
sl@0
   481
	test(thread2.Create(_L("Thread2"),MutexThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);			 
sl@0
   482
	TRequestStatus stat1,stat2;
sl@0
   483
	thread1.Logon(stat1);
sl@0
   484
	thread2.Logon(stat2);
sl@0
   485
	test(stat1==KRequestPending);
sl@0
   486
	test(stat2==KRequestPending);
sl@0
   487
	thread1.Resume(); 
sl@0
   488
	thread2.Resume();
sl@0
   489
	User::WaitForRequest(stat1);
sl@0
   490
	User::WaitForRequest(stat2);
sl@0
   491
	test(stat1==KErrNone);
sl@0
   492
	test(stat2==KErrNone); 
sl@0
   493
	TInt thread1ActualCount=0; 
sl@0
   494
	TInt thread2ActualCount=0;
sl@0
   495
	TInt ii=0;
sl@0
   496
	while(ii<KMaxArraySize)
sl@0
   497
		{
sl@0
   498
		if (array[ii]==EThread1ID)
sl@0
   499
			thread1ActualCount++;
sl@0
   500
		if (array[ii]==EThread2ID)
sl@0
   501
			thread2ActualCount++;
sl@0
   502
		ii++;
sl@0
   503
		}
sl@0
   504
	test.Printf(_L("T1 %d T1ACT %d T2 %d T2ACT %d"),thread1Count,thread1ActualCount,thread2Count,thread2ActualCount);
sl@0
   505
	test(thread1ActualCount==thread1Count);
sl@0
   506
	test(thread2ActualCount==thread2Count);
sl@0
   507
	test(thread1Count==thread2Count);
sl@0
   508
	test(thread1Count==(KMaxArraySize>>1));
sl@0
   509
	
sl@0
   510
	test.Next(_L("Close"));
sl@0
   511
	CLOSE_AND_WAIT(thread1);
sl@0
   512
	CLOSE_AND_WAIT(thread2);
sl@0
   513
	mutex.Close();
sl@0
   514
	test.End();
sl@0
   515
	}
sl@0
   516
sl@0
   517
void TestCriticalSection()
sl@0
   518
//
sl@0
   519
//As TestMutex, but for RCriticalSection
sl@0
   520
//
sl@0
   521
	{
sl@0
   522
	
sl@0
   523
	test.Start(_L("Create"));
sl@0
   524
	test(criticalSn.CreateLocal()==KErrNone);
sl@0
   525
sl@0
   526
/***************** TO DO ***********************
sl@0
   527
sl@0
   528
	test.Next(_L("Find"));
sl@0
   529
//
sl@0
   530
// Test finding the RCriticalSection
sl@0
   531
//
sl@0
   532
	TFindCriticalSection find;
sl@0
   533
	TFullName fullName;
sl@0
   534
	fullName=criticalSn.FullName();
sl@0
   535
	find.Find(fullName);
sl@0
   536
	test(find.Next(fullName)==KErrNone);
sl@0
   537
	test(fullName==criticalSn.FullName());
sl@0
   538
sl@0
   539
************************************************/
sl@0
   540
sl@0
   541
	test.Next(_L("Threads writing to arrays test"));
sl@0
   542
//
sl@0
   543
// Create two threads which write to two arrays. The arrays and indexs
sl@0
   544
// are global and each thread writes an identifier to the arrays. For
sl@0
   545
// one array the writing and updating of the index is wrapped in a critical
sl@0
   546
// section pair. The other array is a control and is not wrapaped within
sl@0
   547
// a critical section. Each thread records the number of instances it
sl@0
   548
// "thinks" it wrote to each array. For the mutex controlled array the
sl@0
   549
// actual instances written to the array should always be the same as the
sl@0
   550
// threads think.
sl@0
   551
//
sl@0
   552
	arrayIndex=0;
sl@0
   553
	RThread thread1,thread2;	
sl@0
   554
	test(thread1.Create(_L("Thread1"),CriticalSnThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);
sl@0
   555
	test(thread2.Create(_L("Thread2"),CriticalSnThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);			 
sl@0
   556
	TRequestStatus stat1,stat2;
sl@0
   557
	thread1.Logon(stat1);
sl@0
   558
	thread2.Logon(stat2);
sl@0
   559
	test(stat1==KRequestPending);
sl@0
   560
	test(stat2==KRequestPending);
sl@0
   561
	thread1.Resume(); 
sl@0
   562
	thread2.Resume();
sl@0
   563
	User::WaitForRequest(stat1);
sl@0
   564
	User::WaitForRequest(stat2);
sl@0
   565
	test(stat1==KErrNone);
sl@0
   566
	test(stat2==KErrNone); 
sl@0
   567
	TInt thread1ActualCount=0; 
sl@0
   568
	TInt thread2ActualCount=0;
sl@0
   569
	TInt ii=0;
sl@0
   570
	while(ii<KMaxArraySize)
sl@0
   571
		{
sl@0
   572
		if (array[ii]==EThread1ID)
sl@0
   573
			thread1ActualCount++;
sl@0
   574
		if (array[ii]==EThread2ID)
sl@0
   575
			thread2ActualCount++;
sl@0
   576
		ii++;
sl@0
   577
		}
sl@0
   578
	test(thread1ActualCount==thread1Count);
sl@0
   579
	test(thread2ActualCount==thread2Count);
sl@0
   580
	test(thread1Count==thread2Count);
sl@0
   581
	test(thread1Count==(KMaxArraySize>>1));
sl@0
   582
sl@0
   583
	test.Next(_L("Close"));
sl@0
   584
	CLOSE_AND_WAIT(thread1);
sl@0
   585
	CLOSE_AND_WAIT(thread2);
sl@0
   586
	criticalSn.Close();
sl@0
   587
	test.End();
sl@0
   588
	}
sl@0
   589
sl@0
   590
sl@0
   591
GLDEF_C TInt E32Main()
sl@0
   592
	{	
sl@0
   593
sl@0
   594
	test.Title();
sl@0
   595
 	__UHEAP_MARK;
sl@0
   596
	test.Start(_L("Test RSemaphore"));
sl@0
   597
	TestSemaphore();
sl@0
   598
	TestSemaphore2();
sl@0
   599
	test.Next(_L("Test RMutex"));
sl@0
   600
	TestMutex();
sl@0
   601
	TestMutex2();
sl@0
   602
	test.Next(_L("Test RCriticalSection"));
sl@0
   603
	TestCriticalSection();
sl@0
   604
	test.End();
sl@0
   605
	__UHEAP_MARKEND;
sl@0
   606
	return(KErrNone);
sl@0
   607
	}
sl@0
   608
sl@0
   609