os/kernelhwsrv/kerneltest/e32test/emi/d_emitest.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) 2005-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\emi\d_emitest.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <kernel/kern_priv.h>
sl@0
    19
#include "d_emitest.h"
sl@0
    20
#include "d_emitest_dev.h"
sl@0
    21
#include <kernel/emi.h>
sl@0
    22
sl@0
    23
//
sl@0
    24
// DEMITestFactory
sl@0
    25
//
sl@0
    26
sl@0
    27
/*
sl@0
    28
  Standard export function for LDDs. This creates a DLogicalDevice derived object,
sl@0
    29
  in this case, our DEMITestFactory
sl@0
    30
*/
sl@0
    31
DECLARE_STANDARD_LDD()
sl@0
    32
	{
sl@0
    33
	return new DEMITestFactory;
sl@0
    34
	}
sl@0
    35
sl@0
    36
DEMITestFactory::DEMITestFactory()
sl@0
    37
	{
sl@0
    38
	}
sl@0
    39
sl@0
    40
DEMITestFactory::~DEMITestFactory()
sl@0
    41
	{
sl@0
    42
	}
sl@0
    43
sl@0
    44
/*
sl@0
    45
  Second stage constructor for DEMITestFactory.
sl@0
    46
  This must at least set a name for the driver object.
sl@0
    47
sl@0
    48
  @return KErrNone or standard error code.
sl@0
    49
*/
sl@0
    50
TInt DEMITestFactory::Install()
sl@0
    51
	{
sl@0
    52
	return SetName(&KEMITestName);
sl@0
    53
	}
sl@0
    54
sl@0
    55
/*
sl@0
    56
  Return the drivers capabilities.
sl@0
    57
  Called in the response to an RDevice::GetCaps() request.
sl@0
    58
  The thread is in a critical section.
sl@0
    59
sl@0
    60
  @param aDes Descriptor to write capabilities information into
sl@0
    61
*/
sl@0
    62
void DEMITestFactory::GetCaps(TDes8&) const
sl@0
    63
	{
sl@0
    64
	}
sl@0
    65
sl@0
    66
/*
sl@0
    67
  Called by the kernel's device driver framework to create a Logical Channel.
sl@0
    68
  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
sl@0
    69
  (E.g. through a call to RBusLogicalChannel::DoCreate)
sl@0
    70
  The thread is in a critical section.
sl@0
    71
sl@0
    72
  @param aChannel Set to point to the created Logical Channel
sl@0
    73
sl@0
    74
  @return KErrNone or standard error code.
sl@0
    75
*/
sl@0
    76
TInt DEMITestFactory::Create(DLogicalChannelBase*& aChannel)
sl@0
    77
	{
sl@0
    78
	aChannel=new DEMITestChannel;
sl@0
    79
	if(!aChannel)
sl@0
    80
		return KErrNoMemory;
sl@0
    81
sl@0
    82
	return KErrNone;
sl@0
    83
	}
sl@0
    84
sl@0
    85
sl@0
    86
//
sl@0
    87
// Logical Channel
sl@0
    88
//
sl@0
    89
sl@0
    90
DEMITestChannel::DEMITestChannel()
sl@0
    91
: iTagMaskDFC(TagMaskDFC,NULL,1)
sl@0
    92
	{
sl@0
    93
	// Get pointer to client threads DThread object
sl@0
    94
	iClient=&Kern::CurrentThread();
sl@0
    95
	// Open a reference on client thread so it's control block can't dissapear until
sl@0
    96
	// this driver has finished with it.
sl@0
    97
	((DObject*)iClient)->Open();
sl@0
    98
	}
sl@0
    99
sl@0
   100
DEMITestChannel::~DEMITestChannel()
sl@0
   101
	{
sl@0
   102
	// Stop EMI, incase it wannt stopped manually.
sl@0
   103
  	EMI::TaskEventLogging(EFalse,0,NULL,NULL);
sl@0
   104
  	EMI::SetMask(0);
sl@0
   105
sl@0
   106
	// Close our reference on the client thread
sl@0
   107
	Kern::SafeClose((DObject*&)iClient,NULL);
sl@0
   108
	}
sl@0
   109
sl@0
   110
/*
sl@0
   111
  Second stage constructor called by the kernel's device driver framework.
sl@0
   112
  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
sl@0
   113
  (E.g. through a call to RBusLogicalChannel::DoCreate)
sl@0
   114
  The thread is in a critical section.
sl@0
   115
sl@0
   116
  @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
sl@0
   117
  @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
sl@0
   118
  @param aVer The version argument supplied by the client to RBusLogicalChannel::DoCreate
sl@0
   119
sl@0
   120
  @return KErrNone or standard error code.
sl@0
   121
*/
sl@0
   122
TInt DEMITestChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion&)
sl@0
   123
	{
sl@0
   124
	iTagMaskDFC.SetDfcQ(Kern::DfcQue0());
sl@0
   125
	return KErrNone;
sl@0
   126
	}
sl@0
   127
sl@0
   128
/* 
sl@0
   129
  Normal test monitors
sl@0
   130
*/
sl@0
   131
TInt MyThreadStartMonitor(NThread* aNThread)
sl@0
   132
	{
sl@0
   133
	TTaskEventRecord rec;
sl@0
   134
	rec.iType=128;
sl@0
   135
	rec.iPrevious=((TInt*) aNThread)+1;	// This stops the event getting killed on thread exit.
sl@0
   136
						// This means there is no garantee the thread will still exist when
sl@0
   137
						// the record is read. This is only safe here as the test code never 
sl@0
   138
						// attempts to derefrance this pointer.
sl@0
   139
	EMI::AddTaskEvent(rec);
sl@0
   140
	return 0;
sl@0
   141
	}
sl@0
   142
sl@0
   143
sl@0
   144
void MyThreadExitMonitor(NThread* aNThread)
sl@0
   145
	{
sl@0
   146
	TTaskEventRecord rec;
sl@0
   147
	rec.iType=129;
sl@0
   148
	rec.iPrevious=aNThread;
sl@0
   149
	EMI::AddTaskEvent(rec);
sl@0
   150
	}
sl@0
   151
/* 
sl@0
   152
  Stress test monitors
sl@0
   153
  
sl@0
   154
  Vems =	 1: Passed.
sl@0
   155
  			 0: No monitors called.
sl@0
   156
  			-1: Wrong Exit monitor callled.
sl@0
   157
  			-2: Exit call before StartMonitor
sl@0
   158
  			-3: Jibberish VEMs value. (or anything ending 5-9)
sl@0
   159
  			-4: Exit called multiple times, 1st time ok.
sl@0
   160
  			<-9: Exit called multiple times.  See last digit for status 1st time.
sl@0
   161
  			Stops couting after -1000, where its clearly very sick!
sl@0
   162
*/
sl@0
   163
sl@0
   164
sl@0
   165
TInt SoakStartMonitor1(NThread* aNThread)
sl@0
   166
	{
sl@0
   167
 	EMI::SetThreadVemsData(aNThread,(TAny*)1000);
sl@0
   168
 	return 0;
sl@0
   169
	}
sl@0
   170
	
sl@0
   171
TInt SoakStartMonitor2(NThread* aNThread)
sl@0
   172
	{
sl@0
   173
 	EMI::SetThreadVemsData(aNThread,(TAny*)2000);
sl@0
   174
 	return 0;
sl@0
   175
	}
sl@0
   176
sl@0
   177
sl@0
   178
sl@0
   179
inline void SoakExitMonitor(NThread* aNThread, TInt aOwner)
sl@0
   180
	{
sl@0
   181
	TInt val = (TInt) EMI::GetThreadVemsData(aNThread);
sl@0
   182
	
sl@0
   183
	if (val>-1)
sl@0
   184
		{
sl@0
   185
		TInt notOwner = (aOwner==1000?2000:1000);
sl@0
   186
sl@0
   187
		if (val==aOwner)
sl@0
   188
			EMI::SetThreadVemsData(aNThread,(TAny*)1);
sl@0
   189
		else if (val==notOwner)
sl@0
   190
			EMI::SetThreadVemsData(aNThread,(TAny*)-1);
sl@0
   191
		else if (val==0)
sl@0
   192
			EMI::SetThreadVemsData(aNThread,(TAny*)-2);
sl@0
   193
		else if (val==1)
sl@0
   194
			EMI::SetThreadVemsData(aNThread,(TAny*)-4);
sl@0
   195
		else
sl@0
   196
			EMI::SetThreadVemsData(aNThread,(TAny*)-3);
sl@0
   197
		}
sl@0
   198
	else
sl@0
   199
		{
sl@0
   200
		if (val>-1000)
sl@0
   201
			EMI::SetThreadVemsData(aNThread,(TAny*)(val-10));
sl@0
   202
		else
sl@0
   203
			EMI::SetThreadVemsData(aNThread,(TAny*)val);
sl@0
   204
		}
sl@0
   205
	}
sl@0
   206
	
sl@0
   207
void SoakExitMonitor1(NThread* aNThread)
sl@0
   208
	{
sl@0
   209
	SoakExitMonitor(aNThread,1000);
sl@0
   210
	}
sl@0
   211
void SoakExitMonitor2(NThread* aNThread)
sl@0
   212
	{
sl@0
   213
	SoakExitMonitor(aNThread,2000);
sl@0
   214
	}
sl@0
   215
sl@0
   216
/*
sl@0
   217
  Process synchronous requests
sl@0
   218
*/
sl@0
   219
TInt DEMITestChannel::Request(TInt aFunction, TAny* a1, TAny* a2)
sl@0
   220
	{
sl@0
   221
	TInt r=KErrNotSupported; 
sl@0
   222
	TTaskEventRecord rec;
sl@0
   223
	
sl@0
   224
	switch (aFunction)
sl@0
   225
		{
sl@0
   226
		case REMITest::ETaskEventLogging:
sl@0
   227
			{
sl@0
   228
			
sl@0
   229
			NKern::ThreadEnterCS();
sl@0
   230
			
sl@0
   231
			TMonitors mon = (TMonitors) ((TInt)a1 >> 1);
sl@0
   232
			TBool logging = (TBool) ((TInt)a1 & 1);
sl@0
   233
sl@0
   234
			switch (mon)
sl@0
   235
				{
sl@0
   236
				case ENone: r = EMI::TaskEventLogging(logging,(TInt) a2,NULL,NULL);
sl@0
   237
				break;
sl@0
   238
				case ENormal: r = EMI::TaskEventLogging(logging,(TInt) a2,&MyThreadStartMonitor,&MyThreadExitMonitor);
sl@0
   239
				break;
sl@0
   240
				case EStressFirst:r = EMI::TaskEventLogging(logging,(TInt) a2,SoakStartMonitor1,SoakExitMonitor1);
sl@0
   241
				break;
sl@0
   242
				case EStressSecond:r = EMI::TaskEventLogging(logging,(TInt) a2,SoakStartMonitor2,SoakExitMonitor2);
sl@0
   243
				}
sl@0
   244
			NKern::ThreadLeaveCS();	
sl@0
   245
			return r;
sl@0
   246
			}
sl@0
   247
		case REMITest::EGetTaskEvent:
sl@0
   248
			r = (TInt) EMI::GetTaskEvent(rec);
sl@0
   249
			if (r)
sl@0
   250
				kumemput(a1,&rec,sizeof(TTaskEventRecord));
sl@0
   251
			return r;
sl@0
   252
		case REMITest::EAddTaskEvent:
sl@0
   253
			kumemget(&rec,a1,sizeof(TTaskEventRecord));
sl@0
   254
			return (TInt) EMI::AddTaskEvent(rec);
sl@0
   255
		case REMITest::EGetIdleThread:
sl@0
   256
			return (TInt) EMI::GetIdleThread(); 
sl@0
   257
		case REMITest::EGetSigmaThread:
sl@0
   258
			return (TInt) EMI::GetSigmaThread(); 
sl@0
   259
		case REMITest::ESetVEMSData:
sl@0
   260
			EMI::SetThreadVemsData((NThread*) a1,a2);
sl@0
   261
			return KErrNone;
sl@0
   262
		case REMITest::EGetVEMSData:
sl@0
   263
			return (TInt) EMI::GetThreadVemsData((NThread*) a1);
sl@0
   264
		case REMITest::ESetThreadLoggable:
sl@0
   265
			EMI::SetThreadLoggable((NThread*) a1,(TBool) a2);
sl@0
   266
			return KErrNone;
sl@0
   267
		case REMITest::EGetThreadLoggable:
sl@0
   268
			return (TInt) EMI::GetThreadLoggable((NThread*) a1);
sl@0
   269
		case REMITest::ESetThreadTag:
sl@0
   270
			EMI::SetThreadTag((NThread*) a1,(TUint32) a2);
sl@0
   271
			return KErrNone;
sl@0
   272
		case REMITest::EGetThreadTag:
sl@0
   273
			return (TInt) EMI::GetThreadTag((NThread*) a1);
sl@0
   274
		case REMITest::ESetMask:
sl@0
   275
			EMI::SetMask((TInt) a1);
sl@0
   276
			return KErrNone;
sl@0
   277
		case REMITest::EGetMask:
sl@0
   278
			return EMI::GetMask();			
sl@0
   279
		case REMITest::ESetDFC:
sl@0
   280
			EMI::SetDfc(&iTagMaskDFC, 0);
sl@0
   281
			return KErrNone;
sl@0
   282
		case REMITest::ESetState:
sl@0
   283
			EMI::SetState((TInt) a1);
sl@0
   284
			return KErrNone;
sl@0
   285
		case REMITest::EGetState:
sl@0
   286
			return EMI::GetState();
sl@0
   287
		case REMITest::EGetNThread:
sl@0
   288
			{
sl@0
   289
			DThread* myThread;
sl@0
   290
			TInt myNThread;
sl@0
   291
			NKern::LockSystem();
sl@0
   292
			
sl@0
   293
			myThread = (DThread* ) Kern::CurrentThread().ObjectFromHandle((TInt)a1,EThread);
sl@0
   294
			myNThread=  (TInt) (myThread==NULL?NULL:&myThread->iNThread);
sl@0
   295
			NKern::UnlockSystem();
sl@0
   296
			return myNThread;
sl@0
   297
			}
sl@0
   298
		case REMITest::EAfterIdle:
sl@0
   299
			EMI::AfterIdle((TInt) a1);			
sl@0
   300
			return KErrNone;
sl@0
   301
	
sl@0
   302
		default:
sl@0
   303
			return KErrNotSupported;
sl@0
   304
		}
sl@0
   305
	}
sl@0
   306
	
sl@0
   307
/*
sl@0
   308
  DFC callback which gets triggered when the EMI tag anded with thread mask is true.
sl@0
   309
  Sets EMI state to be the value returned from GetDfcTriggerTag.
sl@0
   310
*/
sl@0
   311
void DEMITestChannel::TagMaskDFC(TAny*)
sl@0
   312
	{
sl@0
   313
	EMI::SetState(EMI::GetDfcTriggerTag());
sl@0
   314
	EMI::SetMask(0);
sl@0
   315
	}