kerneltest/e32test/emi/d_emitest.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 	}