os/kernelhwsrv/kerneltest/e32test/system/t_dobject.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2004-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\system\t_dobject.cpp
sl@0
    15
// Overview:
sl@0
    16
// Test RObjectIx strategy of memory reallocation and 
sl@0
    17
// free list maintenance.
sl@0
    18
// Test DObjectCon findhandle methods
sl@0
    19
// API Information:
sl@0
    20
// DObject, RObjectIx
sl@0
    21
// Details:
sl@0
    22
// - Add a number of DObjects to RObjectIx, then remove them 
sl@0
    23
// in the same order. Verify results are as expected. Time
sl@0
    24
// how long the process takes to complete.
sl@0
    25
// - Add a number of DObjects to RObjectIx, then remove them
sl@0
    26
// in the reverse order. Verify results are as expected. Time
sl@0
    27
// how long the process takes to complete.
sl@0
    28
// - Add and remove a random number of DObjects to/from RObjectIx.
sl@0
    29
// Time how long the process takes to complete.
sl@0
    30
// Platforms/Drives/Compatibility:
sl@0
    31
// All.
sl@0
    32
// Assumptions/Requirement/Pre-requisites:
sl@0
    33
// Failures and causes:
sl@0
    34
// Base Port information:
sl@0
    35
// 
sl@0
    36
//
sl@0
    37
sl@0
    38
#define __E32TEST_EXTENSION__
sl@0
    39
#include <e32test.h>
sl@0
    40
#include <e32math.h>
sl@0
    41
#include "d_dobject.h"
sl@0
    42
sl@0
    43
LOCAL_D RTest test(_L("T_DOBJECT"));
sl@0
    44
sl@0
    45
TInt TestRObjectIxAccess(TAny* aRObjectIxPtr)
sl@0
    46
	{
sl@0
    47
	const TInt  KConcurrentDObjectTestRepeats = 1;
sl@0
    48
	
sl@0
    49
	RTestDObject  ldd;
sl@0
    50
	TInt  ret;
sl@0
    51
	
sl@0
    52
	ret = ldd.Open();
sl@0
    53
	if (ret == KErrNone)
sl@0
    54
		{
sl@0
    55
		for (TInt  repeat = 0;  repeat < KConcurrentDObjectTestRepeats;  repeat++)
sl@0
    56
			{
sl@0
    57
			ret = ldd.RObjectIxThreadTestExerciseIx(aRObjectIxPtr);
sl@0
    58
			if (ret != KErrNone)
sl@0
    59
				{
sl@0
    60
				break;
sl@0
    61
				}
sl@0
    62
			}
sl@0
    63
		ldd.Close();
sl@0
    64
		}
sl@0
    65
	
sl@0
    66
	return ret;
sl@0
    67
	} // TestRObjectIxAccess
sl@0
    68
sl@0
    69
void TestConcurrentRObjectIxAccess(RTestDObject& aLdd)
sl@0
    70
	{
sl@0
    71
	const TInt  KConcurrentDObjectThreads = 4;
sl@0
    72
	_LIT(KConcurrentDObjectThreadName, "T_DObject_Thread");
sl@0
    73
	
sl@0
    74
	TInt ret;
sl@0
    75
	
sl@0
    76
	//
sl@0
    77
	// Create a RObjectIx in the driver (pointer not valid user side!)...
sl@0
    78
	//
sl@0
    79
	void*  objectIxPtr = NULL;
sl@0
    80
	
sl@0
    81
	ret = aLdd.RObjectIxThreadTestCreateIx(objectIxPtr);
sl@0
    82
	test_KErrNone(ret);
sl@0
    83
	
sl@0
    84
	//
sl@0
    85
	// Run KConcurrentDObjectThreads number of threads which random add/remove
sl@0
    86
	// DObjects to the same RObjectIx...
sl@0
    87
	//
sl@0
    88
	RThread  threadHandle[KConcurrentDObjectThreads];
sl@0
    89
	TRequestStatus  status[KConcurrentDObjectThreads];
sl@0
    90
	TBuf<32>  threadName;
sl@0
    91
	TInt  thread;
sl@0
    92
sl@0
    93
	for (thread = 0;  thread < KConcurrentDObjectThreads;  thread++)
sl@0
    94
		{
sl@0
    95
		threadName.Copy(KConcurrentDObjectThreadName);
sl@0
    96
		threadName.AppendNum(thread);
sl@0
    97
		
sl@0
    98
		ret = threadHandle[thread].Create(threadName, TestRObjectIxAccess, KDefaultStackSize, NULL, objectIxPtr);
sl@0
    99
		test_KErrNone(ret);
sl@0
   100
sl@0
   101
		threadHandle[thread].Logon(status[thread]);
sl@0
   102
		}
sl@0
   103
sl@0
   104
	//
sl@0
   105
	// The test thread must be higher priority to ensure all the threads start.
sl@0
   106
	// All the threads are then resumed and allowed to run to completion...
sl@0
   107
	//
sl@0
   108
	RThread().SetPriority(EPriorityMore);
sl@0
   109
sl@0
   110
	for (thread = 0;  thread < KConcurrentDObjectThreads;  thread++)
sl@0
   111
		{
sl@0
   112
		threadHandle[thread].Resume();
sl@0
   113
		}
sl@0
   114
sl@0
   115
	for (thread = 0;  thread < KConcurrentDObjectThreads;  thread++)
sl@0
   116
		{
sl@0
   117
		User::WaitForRequest(status[thread]);
sl@0
   118
		test_KErrNone(status[thread].Int());
sl@0
   119
		CLOSE_AND_WAIT(threadHandle[thread]);
sl@0
   120
		}
sl@0
   121
	
sl@0
   122
	RThread().SetPriority(EPriorityNormal);
sl@0
   123
sl@0
   124
	//
sl@0
   125
	// Free the RObjectIx in the driver...
sl@0
   126
	//
sl@0
   127
	ret = aLdd.RObjectIxThreadTestFreeIx(objectIxPtr);
sl@0
   128
	test_KErrNone(ret);
sl@0
   129
	} // TestConcurrentRObjectIxAccess
sl@0
   130
sl@0
   131
sl@0
   132
void ListAllMutexes()
sl@0
   133
	{
sl@0
   134
	test.Printf(_L("Mutexes:\n"));
sl@0
   135
	TFullName name;
sl@0
   136
	TFindMutex find;
sl@0
   137
	while (find.Next(name) == KErrNone)
sl@0
   138
		{
sl@0
   139
		test.Printf(_L("  %S (find handle == %08x)\n"), &name, find.Handle());
sl@0
   140
		}
sl@0
   141
	}
sl@0
   142
sl@0
   143
const TInt KObjectCount = 20;
sl@0
   144
_LIT(KDoubleMatch, "*double*");
sl@0
   145
_LIT(KTrippleMatch, "*tripple*");
sl@0
   146
sl@0
   147
RMutex Mutexes[KObjectCount];
sl@0
   148
TBuf<32> ObjectName;
sl@0
   149
sl@0
   150
const TDesC& MutexName(TInt i)
sl@0
   151
	{
sl@0
   152
	ObjectName.Zero();
sl@0
   153
	ObjectName.AppendFormat(_L("Mutex_%02d"), i);
sl@0
   154
	if (i % 2 == 0)
sl@0
   155
		ObjectName.Append(_L("_double"));
sl@0
   156
	if (i % 3 == 0)
sl@0
   157
		ObjectName.Append(_L("_tripple"));
sl@0
   158
	return ObjectName;
sl@0
   159
	}
sl@0
   160
sl@0
   161
void CreateMutexes()
sl@0
   162
	{
sl@0
   163
	for (TInt i = 0 ; i < KObjectCount ; ++i)
sl@0
   164
		{
sl@0
   165
		test(Mutexes[i].CreateGlobal(MutexName(i)) == KErrNone);
sl@0
   166
		}
sl@0
   167
	}
sl@0
   168
sl@0
   169
void DeleteMutexes()
sl@0
   170
	{
sl@0
   171
	for (TInt i = 0 ; i < KObjectCount ; ++i)
sl@0
   172
		{
sl@0
   173
		Mutexes[i].Close();
sl@0
   174
		}
sl@0
   175
	}
sl@0
   176
sl@0
   177
void TestMutexesCreated()
sl@0
   178
	{
sl@0
   179
	test.Next(_L("Test mutexes have been created"));
sl@0
   180
	
sl@0
   181
	TFullName name;
sl@0
   182
sl@0
   183
	for (TInt i = 0 ; i < KObjectCount ; ++i)
sl@0
   184
		{
sl@0
   185
		TFindMutex find(MutexName(i));
sl@0
   186
		test(find.Next(name) == KErrNone);
sl@0
   187
		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
sl@0
   188
		}
sl@0
   189
	}
sl@0
   190
sl@0
   191
void TestMutexesDeleted()
sl@0
   192
	{
sl@0
   193
	test.Next(_L("Test mutexes deleted"));
sl@0
   194
sl@0
   195
	TFullName name;
sl@0
   196
sl@0
   197
	for (TInt i = 0 ; i < KObjectCount ; ++i)
sl@0
   198
		{
sl@0
   199
		TFindMutex find(MutexName(i));
sl@0
   200
		test(find.Next(name) == KErrNotFound);
sl@0
   201
		}
sl@0
   202
	}
sl@0
   203
sl@0
   204
sl@0
   205
void TestFindSpecificMutex()
sl@0
   206
	{
sl@0
   207
	test.Next(_L("Test finding specific mutexes"));
sl@0
   208
	
sl@0
   209
	for (TInt i = 0 ; i < KObjectCount ; ++i)
sl@0
   210
		{
sl@0
   211
		TFullName name;
sl@0
   212
		TFindMutex find(MutexName(i));
sl@0
   213
		test(find.Next(name) == KErrNone);
sl@0
   214
		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
sl@0
   215
		test(name == MutexName(i));
sl@0
   216
		RMutex mutex;
sl@0
   217
		test(mutex.Open(find) == KErrNone);
sl@0
   218
		test(mutex.Name() == MutexName(i));
sl@0
   219
		mutex.Close();
sl@0
   220
		test(find.Next(name) == KErrNotFound);
sl@0
   221
		}	
sl@0
   222
	}
sl@0
   223
sl@0
   224
void TestFindMutexGroups()
sl@0
   225
	{
sl@0
   226
	test.Next(_L("Test finding groups of mutexes using wildcard name matching"));
sl@0
   227
sl@0
   228
	TFullName name;
sl@0
   229
	TInt i;
sl@0
   230
	
sl@0
   231
	TFindMutex find2(KDoubleMatch);
sl@0
   232
	for (i = 0 ; i < KObjectCount ; i += 2)
sl@0
   233
		{
sl@0
   234
		test(find2.Next(name) == KErrNone);
sl@0
   235
		test.Printf(_L("  %02d: found handle %08x\n"), i, find2.Handle());
sl@0
   236
		test(name == MutexName(i));
sl@0
   237
		}
sl@0
   238
	test(find2.Next(name) == KErrNotFound);
sl@0
   239
sl@0
   240
	TFindMutex find3(KTrippleMatch);
sl@0
   241
	for (i = 0 ; i < KObjectCount ; i += 3)
sl@0
   242
		{
sl@0
   243
		test(find3.Next(name) == KErrNone);
sl@0
   244
		test.Printf(_L("  %02d: found handle %08x\n"), i, find3.Handle());
sl@0
   245
		test(name == MutexName(i));
sl@0
   246
		}
sl@0
   247
	test(find3.Next(name) == KErrNotFound);
sl@0
   248
	}
sl@0
   249
sl@0
   250
void TestMatchChange()
sl@0
   251
	{
sl@0
   252
	test.Next(_L("Test changing match half way through find"));
sl@0
   253
sl@0
   254
sl@0
   255
	TFullName name;
sl@0
   256
	TInt i;
sl@0
   257
	
sl@0
   258
	TFindMutex find(KDoubleMatch);
sl@0
   259
	for (i = 0 ; i < KObjectCount/2 ; i += 2)
sl@0
   260
		{
sl@0
   261
		test(find.Next(name) == KErrNone);
sl@0
   262
		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
sl@0
   263
		test(name == MutexName(i));
sl@0
   264
		}
sl@0
   265
sl@0
   266
	find.Find(KTrippleMatch);
sl@0
   267
	for (i = 0 ; i < KObjectCount ; i += 3)
sl@0
   268
		{
sl@0
   269
		test(find.Next(name) == KErrNone);
sl@0
   270
		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
sl@0
   271
		test(name == MutexName(i));
sl@0
   272
		}
sl@0
   273
	test(find.Next(name) == KErrNotFound);
sl@0
   274
	}
sl@0
   275
sl@0
   276
void TestFindAndDeleteMutex1()
sl@0
   277
	{
sl@0
   278
	test.Next(_L("Test finding mutexes when the last found object has been deleted"));
sl@0
   279
sl@0
   280
	// Find and delete even mutexes
sl@0
   281
	TFullName name;
sl@0
   282
	TInt i;
sl@0
   283
	for (i = 0 ; i < KObjectCount ; i += 2)
sl@0
   284
		{
sl@0
   285
		TFindMutex find2(MutexName(i));
sl@0
   286
		test(find2.Next(name) == KErrNone);
sl@0
   287
		test.Printf(_L("  %02d: found handle %08x\n"), i, find2.Handle());
sl@0
   288
		Mutexes[i].Close();
sl@0
   289
		RMutex mutex;
sl@0
   290
		test(mutex.Open(find2) == KErrNotFound);
sl@0
   291
		}
sl@0
   292
sl@0
   293
	// Check odd mutexes remaining
sl@0
   294
	for (i = 1 ; i < KObjectCount ; i += 2)
sl@0
   295
		{
sl@0
   296
		TFindMutex find(MutexName(i));
sl@0
   297
		test(find.Next(name) == KErrNone);
sl@0
   298
		}
sl@0
   299
	}
sl@0
   300
sl@0
   301
void TestFindAndDeleteMutex2()
sl@0
   302
	{
sl@0
   303
	test.Next(_L("Test finding mutexes when the last found object has moved in the container"));
sl@0
   304
sl@0
   305
	// Find even mutexes and delete odd
sl@0
   306
	TFullName name;
sl@0
   307
	TInt i;
sl@0
   308
	for (i = 0 ; i < KObjectCount ; i += 2)
sl@0
   309
		{
sl@0
   310
		TFindMutex find2(MutexName(i));
sl@0
   311
		test(find2.Next(name) == KErrNone);
sl@0
   312
		test.Printf(_L("  %02d: found handle %08x\n"), i, find2.Handle());
sl@0
   313
		Mutexes[(i+KObjectCount-1)%KObjectCount].Close();	// -1%n = -1 or n-1, unspecified
sl@0
   314
		RMutex mutex;
sl@0
   315
		test(mutex.Open(find2) == KErrNone);
sl@0
   316
		test(mutex.Name() == MutexName(i));
sl@0
   317
		mutex.Close();
sl@0
   318
		}
sl@0
   319
sl@0
   320
	// Check even mutexes remaining
sl@0
   321
	for (i = 0 ; i < KObjectCount ; i += 2)
sl@0
   322
		{
sl@0
   323
		TFindMutex find(MutexName(i));
sl@0
   324
		test(find.Next(name) == KErrNone);
sl@0
   325
		}
sl@0
   326
	
sl@0
   327
	}
sl@0
   328
sl@0
   329
void TestFindWithCreation()
sl@0
   330
	{
sl@0
   331
	test.Next(_L("Test finding mutexes interleaved with creation"));
sl@0
   332
sl@0
   333
	TFullName name;
sl@0
   334
	
sl@0
   335
	for (TInt i = 0 ; i < KObjectCount ; ++i)
sl@0
   336
		{
sl@0
   337
		test(Mutexes[i].CreateGlobal(MutexName(i)) == KErrNone);
sl@0
   338
		TFindMutex find(MutexName(i));
sl@0
   339
		test(find.Next(name) == KErrNone);
sl@0
   340
		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
sl@0
   341
		RMutex mutex;
sl@0
   342
		test(mutex.Open(find) == KErrNone);
sl@0
   343
		test(mutex.Name() == MutexName(i));
sl@0
   344
		mutex.Close();
sl@0
   345
		}
sl@0
   346
	}
sl@0
   347
sl@0
   348
void TestFindWithCreation2()
sl@0
   349
	{
sl@0
   350
	test.Next(_L("Test finding mutexes interleaved with creation and deletion"));
sl@0
   351
sl@0
   352
	TFullName name;
sl@0
   353
sl@0
   354
	for (TInt i = 0 ; i < KObjectCount ; ++i)
sl@0
   355
		{
sl@0
   356
		RMutex mutex;
sl@0
   357
		test(mutex.CreateGlobal(MutexName(0)) == KErrNone);
sl@0
   358
		TFindMutex find(MutexName(0));
sl@0
   359
		test(find.Next(name) == KErrNone);
sl@0
   360
		test(name == MutexName(0));
sl@0
   361
		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
sl@0
   362
		mutex.Close();
sl@0
   363
sl@0
   364
		TFindMutex find2(MutexName(0));
sl@0
   365
		test(find2.Next(name) == KErrNotFound);
sl@0
   366
		}
sl@0
   367
	}
sl@0
   368
sl@0
   369
void TestFindHandleOutOfRange()
sl@0
   370
	{
sl@0
   371
	test.Next(_L("Test finding mutexes when find handle index is off the end of container's array"));
sl@0
   372
sl@0
   373
	TFullName name;
sl@0
   374
sl@0
   375
	for (TInt i = 0 ; i < KObjectCount ; ++i)
sl@0
   376
		{
sl@0
   377
		TFindMutex find(MutexName(i));
sl@0
   378
		test(find.Next(name) == KErrNone);
sl@0
   379
		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
sl@0
   380
		RMutex mutex;
sl@0
   381
		test(mutex.Open(find) == KErrNone);
sl@0
   382
		test(mutex.Name() == MutexName(i));
sl@0
   383
		mutex.Close();
sl@0
   384
sl@0
   385
		// towards the end, suddenly delete half the mutexes
sl@0
   386
		if (i == (3 * KObjectCount) / 4)
sl@0
   387
			{
sl@0
   388
			for (TInt j = 0 ; j < KObjectCount / 2 ; ++j)
sl@0
   389
				Mutexes[j].Close();
sl@0
   390
			}
sl@0
   391
		}
sl@0
   392
	}
sl@0
   393
sl@0
   394
void TestFindHandles()
sl@0
   395
	{
sl@0
   396
	test.Start(_L("Test FindHandle APIs using mutex classes"));
sl@0
   397
sl@0
   398
	CreateMutexes();
sl@0
   399
	ListAllMutexes();
sl@0
   400
	TestMutexesCreated();
sl@0
   401
	TestFindSpecificMutex();
sl@0
   402
	TestFindMutexGroups();
sl@0
   403
	TestMatchChange();
sl@0
   404
	DeleteMutexes();
sl@0
   405
	TestMutexesDeleted();
sl@0
   406
sl@0
   407
	CreateMutexes();
sl@0
   408
	TestFindAndDeleteMutex1();
sl@0
   409
	DeleteMutexes();
sl@0
   410
sl@0
   411
	CreateMutexes();
sl@0
   412
	TestFindHandleOutOfRange();
sl@0
   413
	DeleteMutexes();
sl@0
   414
	
sl@0
   415
	CreateMutexes();
sl@0
   416
	TestFindAndDeleteMutex2();
sl@0
   417
	DeleteMutexes();
sl@0
   418
sl@0
   419
	TestFindWithCreation();
sl@0
   420
	DeleteMutexes();
sl@0
   421
sl@0
   422
	TestFindWithCreation2();
sl@0
   423
	TestMutexesDeleted();
sl@0
   424
	
sl@0
   425
	test.End();
sl@0
   426
	}
sl@0
   427
sl@0
   428
GLDEF_C TInt E32Main()
sl@0
   429
    {
sl@0
   430
	SParam param;
sl@0
   431
	TInt duration, r;
sl@0
   432
	RTestDObject ldd;
sl@0
   433
sl@0
   434
	test.Title();
sl@0
   435
sl@0
   436
	test.Start(_L("Loading test driver..."));
sl@0
   437
sl@0
   438
	r=User::LoadLogicalDevice(KDObjectTestLddName);
sl@0
   439
	test(r==KErrNone || r==KErrAlreadyExists);
sl@0
   440
	r=ldd.Open();
sl@0
   441
	test(r==KErrNone);
sl@0
   442
sl@0
   443
	test.Next(_L("RObjectIxTest1 test ..."));
sl@0
   444
	r=ldd.RObjectIxTest1(duration);
sl@0
   445
	test(KErrNone==r);
sl@0
   446
	test.Printf(_L("... completed in %d kernel ticks\n") , duration);
sl@0
   447
sl@0
   448
	test.Next(_L("RObjectIxTest2 test ..."));
sl@0
   449
	r=ldd.RObjectIxTest2(duration);
sl@0
   450
	test(KErrNone==r);
sl@0
   451
	test.Printf(_L("... completed in %d kernel ticks\n") , duration);
sl@0
   452
sl@0
   453
	test.Next(_L("RObjectIxTest3 test (performance) ..."));
sl@0
   454
	param.iSeed[0] = 0;
sl@0
   455
	param.iSeed[1] = 1;
sl@0
   456
	param.iPerformanceTest = ETrue;
sl@0
   457
	r=ldd.RObjectIxTest3(param);
sl@0
   458
	test(KErrNone==r);
sl@0
   459
	test.Printf(_L("... completed in %d kernel ticks\n") , param.duration);
sl@0
   460
sl@0
   461
	test.Next(_L("RObjectIxTest3 test (random)..."));
sl@0
   462
	param.iSeed[0]=User::TickCount();
sl@0
   463
	param.iSeed[1]=User::TickCount();
sl@0
   464
	param.iPerformanceTest = EFalse;
sl@0
   465
	test.Printf(_L("... seeds=%xh and %xh ..."),param.iSeed[0],param.iSeed[1]);
sl@0
   466
	r=ldd.RObjectIxTest3(param);
sl@0
   467
	test(KErrNone==r);
sl@0
   468
	test.Printf(_L("... completed in %d kernel ticks\n") , param.duration);
sl@0
   469
 
sl@0
   470
	test.Next(_L("RObjectIxTest4 test (reserved slots)..."));
sl@0
   471
	test_KErrNone(ldd.RObjectIxTest4(duration));
sl@0
   472
	test.Printf(_L("... completed in %d kernel ticks\n") , duration);
sl@0
   473
sl@0
   474
	test.Next(_L("Test Concurrent access to RObjectIx"));
sl@0
   475
	TestConcurrentRObjectIxAccess(ldd);
sl@0
   476
sl@0
   477
	test.Next(_L("Test Invalid handle look up"));
sl@0
   478
 	test_KErrNone(ldd.InvalidHandleLookupTest());
sl@0
   479
sl@0
   480
 	test.Next(_L("Test Kern::ValidateName and Kern::ValidateFullName"));
sl@0
   481
 	test_KErrNone(ldd.DObjectNameTest());
sl@0
   482
 
sl@0
   483
	test.Next(_L("Closing test driver"));
sl@0
   484
	ldd.Close();
sl@0
   485
sl@0
   486
	test.Next(_L("FindHandles test"));
sl@0
   487
	TestFindHandles();
sl@0
   488
	
sl@0
   489
	test.End();
sl@0
   490
sl@0
   491
	return(0);
sl@0
   492
	}