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