os/kernelhwsrv/kerneltest/e32test/resourceman/acctst/d_prmacctst.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) 2007-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 //
    15 
    16 #include <kernel/kernel.h>
    17 #include <drivers/resourceman.h>
    18 #include "d_prmacctst.h"
    19 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
    20 #include "../resourceman_psl/rescontrol_psl.h"
    21 #endif // RESOURCE_MANAGER_SIMULATED_PSL
    22 
    23 #define TEST_KERRNONE(x) { TInt  _r = (x); if (_r != KErrNone) \
    24 	Kern::Printf("Test failed: %s line %d error %d", __FILE__, __LINE__, _r); }
    25 #define TEST(x) { if (!(x)) Kern::Printf("Test failed: %s line %d", __FILE__, __LINE__); }
    26 
    27 _LIT(KTestDfcQueBaseName, "PrmIfDfc");
    28 const TInt KTestDfcQuePrority = KMaxDfcPriority - 1;
    29 
    30 //---------------------------------------------------------------------------
    31 
    32 class DPrmIfDevice : public DLogicalDevice
    33 	{
    34 public:
    35 	DPrmIfDevice();
    36 	virtual TInt Install();
    37 	virtual void GetCaps(TDes8& aDes) const;
    38 	virtual TInt Create(DLogicalChannelBase*& aChannel);
    39 	};
    40 
    41 //---------------------------------------------------------------------------
    42 
    43 class DPrmIfChannel : public DLogicalChannel
    44 	{
    45 public:
    46 	DPrmIfChannel();
    47 	~DPrmIfChannel();
    48 protected:
    49 	virtual void HandleMsg(TMessageBase* aMsg);
    50 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
    51 private:
    52 	TInt DoControl(TInt aReqNo, TAny *a1, TAny *a2);
    53 	TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny *a1, TAny *a2);
    54 	void Shutdown();
    55 
    56 public:
    57 	static TUint KernelExtensionClientId;
    58 private:
    59 	DThread*		iUserThread;
    60 	TUint			iClientId;
    61 	HBuf*			iClientName;
    62 	};
    63 
    64 TUint DPrmIfChannel::KernelExtensionClientId = 0;
    65 
    66 void TestCallbackFunction(TUint /* aClientId */,
    67 						  TUint /* aResourceId */,
    68 						  TInt  /* aLevel */,
    69 						  TInt  /* aLevelOwnerId */,
    70 						  TInt  /* aResult */,
    71 						  TAny* aSem);
    72 
    73 //---------------------------------------------------------------------------
    74 
    75 DPrmIfDevice::DPrmIfDevice()
    76 	{
    77 	}
    78 
    79 TInt DPrmIfDevice::Install()
    80 	{
    81 	return SetName(&KPrmIfLddName);
    82 	}
    83 
    84 void DPrmIfDevice::GetCaps(TDes8& /* aDes */) const
    85 	{
    86 	// Not used but required as DLogicalDevice::GetCaps is pure virtual
    87 	}
    88 
    89 TInt DPrmIfDevice::Create(DLogicalChannelBase*& aChannel)
    90 	{
    91 	aChannel = new DPrmIfChannel;
    92 	return aChannel ? KErrNone : KErrNoMemory;
    93 	}
    94 
    95 //---------------------------------------------------------------------------
    96 
    97 DPrmIfChannel::DPrmIfChannel()
    98 	{
    99 	iUserThread = &Kern::CurrentThread();
   100 	((DObject*) iUserThread)->Open();
   101 	}
   102 
   103 DPrmIfChannel::~DPrmIfChannel()
   104 	{
   105 	if(iDfcQ)
   106 	  ((TDynamicDfcQue*)iDfcQ)->Destroy();
   107 	// Close our reference on the client thread
   108 	Kern::SafeClose((DObject*&)iUserThread,NULL);
   109 	}
   110 
   111 void DPrmIfChannel::HandleMsg(TMessageBase *aMsg)
   112 	{
   113 	TThreadMessage& m = *(TThreadMessage*) aMsg;
   114 	TInt id = m.iValue;
   115 
   116 	if (id == (TInt) ECloseMsg)
   117 		{
   118 		m.Complete(KErrNone, EFalse);
   119 		return;
   120 		}
   121 	else if (id == KMaxTInt)
   122 		{
   123 		// DoCancel
   124 		m.Complete(KErrNone, ETrue);
   125 		return;
   126 		}
   127 	else if (id < 0)
   128 		{
   129 		// DoRequest
   130 		TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
   131 		TInt r = DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
   132 		if (r != KErrNone)
   133 			{
   134 			Kern::RequestComplete(iUserThread, pS, r);
   135 			}
   136 		m.Complete(KErrNone, ETrue);
   137 		}
   138 	else
   139 		{
   140 		// DoControl
   141 		TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
   142 		if(r != KErrCompletion)
   143 			{
   144 			m.Complete(r, ETrue);
   145 			}
   146 		}
   147 	}
   148 
   149 TInt DPrmIfChannel::DoCreate(TInt /* aUnit */, const TDesC8* /* aInfo */, const TVersion& /* aVer */)
   150 	{
   151 	TDynamicDfcQue* dfcQ;
   152 	TInt r = Kern::DynamicDfcQCreate(dfcQ, KTestDfcQuePrority, KTestDfcQueBaseName);
   153 	TEST_KERRNONE(r);
   154 	iDfcQ = dfcQ;
   155 	if (r != KErrNone)
   156 		{
   157 		return r;
   158 		}
   159 	SetDfcQ(iDfcQ);
   160 	iMsgQ.Receive();
   161 	return KErrNone;
   162 	}
   163 
   164 TInt DPrmIfChannel::DoControl(TInt aReqNo, TAny *a1, TAny *a2)
   165 	{
   166 	TInt r = KErrNotSupported;
   167 	switch (aReqNo)
   168 		{
   169 		case RPrmIf::EControlOpenClient:
   170 			{
   171 			if (iClientId)
   172 				{
   173 				return KErrAlreadyExists;
   174 				}
   175 			TBuf8<80> clientName;
   176 			r = PowerResourceManager::GetClientName((TUint) a1, (TUint) a1, clientName);
   177 			TEST_KERRNONE(r);
   178 			if (r == KErrNone)
   179 				iClientId = (TUint) a1;
   180 			break;
   181 			}
   182 
   183 		case RPrmIf::EControlGetKernelExtClientId:
   184 			{
   185 			r = Kern::ThreadRawWrite(iUserThread, a1, &KernelExtensionClientId, sizeof(TUint));
   186 			TEST_KERRNONE(r);
   187 			break;
   188 			}
   189 
   190 		case RPrmIf::EControlRegisterClient:
   191 			{
   192 			if (iClientId)
   193 				{
   194 				return KErrAlreadyExists;
   195 				}
   196 			iClientName = HBuf::New(KNameMaxLength);
   197 			r = Kern::ThreadDesRead(iUserThread, a1, *iClientName, 0);
   198 			TEST_KERRNONE(r);
   199 			if (r)
   200 				{
   201 				return r;
   202 				}
   203 			r = PowerResourceManager::RegisterClient(iClientId, *iClientName);
   204 			TEST_KERRNONE(r);
   205 			break;
   206 			}
   207 
   208 		case RPrmIf::EControlDeRegisterClient:
   209 			{
   210 			if (!iClientId)
   211 				{
   212 				return KErrNotReady;
   213 				}
   214 			r = PowerResourceManager::DeRegisterClient(iClientId);
   215 			if (r == KErrNone)
   216 				{
   217 				if (iClientId == KernelExtensionClientId)
   218 					{
   219 					// Set it to 0 so it cannot be re-opened
   220 					KernelExtensionClientId = 0;
   221 					}
   222 				delete iClientName;
   223 				iClientId = 0;
   224 				}
   225 			break;
   226 			}
   227 
   228 		case RPrmIf::EControlGetInfoOnResourcesInUseByClient:
   229 			{
   230 			if (!iClientId)
   231 				{
   232 				return KErrNotReady;
   233 				}
   234 			TUint nores;
   235 			r = PowerResourceManager::GetNumResourcesInUseByClient(iClientId, (TUint) a1, nores);
   236 			TEST_KERRNONE(r);
   237 			if (r)
   238 				{
   239 				return r;
   240 				}
   241 			if (nores > 0)
   242 				{
   243 				HBuf* resinfo;
   244 				resinfo = HBuf::New(nores * sizeof(TResInfo));
   245 				TEST(resinfo != NULL);
   246 				if (resinfo == NULL)
   247 					{
   248 					return KErrNoMemory;
   249 					}
   250 				r = PowerResourceManager::GetInfoOnResourcesInUseByClient(iClientId, (TUint) a1, nores, (TAny*) resinfo);
   251 				TEST_KERRNONE(r);
   252 				if (r)
   253 					{
   254 					delete resinfo;
   255 					return r;
   256 					}
   257 				r = Kern::ThreadDesWrite(iUserThread, a2, *resinfo, 0);
   258 				TEST_KERRNONE(r);
   259 				delete resinfo;
   260 				}
   261 			break;
   262 			}
   263 
   264 		case RPrmIf::EControlChangeResourceState:
   265 			{
   266 			if (!iClientId)
   267 				{
   268 				return KErrNotReady;
   269 				}
   270 			r = PowerResourceManager::ChangeResourceState(iClientId, (TUint) a1, (TInt) a2);
   271 			break;
   272 			}
   273 
   274 		case RPrmIf::EControlGetResourceState:
   275 			{
   276 			if (!iClientId)
   277 				{
   278 				return KErrNotReady;
   279 				}
   280 			TInt state;
   281 			TInt levelowner;
   282 			r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, EFalse, state, levelowner);
   283 			TEST_KERRNONE(r);
   284 			if (r)
   285 				{
   286 				return r;
   287 				}
   288 			r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt));
   289 			TEST_KERRNONE(r);
   290 			break;
   291 			}
   292 
   293 		case RPrmIf::EControlGetResourceStateCached:
   294 			{
   295 			if (!iClientId)
   296 				{
   297 				return KErrNotReady;
   298 				}
   299 			TInt state;
   300 			TInt levelowner;
   301 			r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, ETrue, state, levelowner);
   302 			TEST_KERRNONE(r);
   303 			if (r)
   304 				{
   305 				return r;
   306 				}
   307 			r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt));
   308 			TEST_KERRNONE(r);
   309 			break;
   310 			}
   311 
   312 		case RPrmIf::EControlGetLevelOwner:
   313 			{
   314 			if (!iClientId)
   315 				{
   316 				return KErrNotReady;
   317 				}
   318 			TInt state;
   319 			TInt levelowner;
   320 			r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, EFalse, state, levelowner);
   321 			TEST_KERRNONE(r);
   322 			if (r)
   323 				{
   324 				return r;
   325 				}
   326 			r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &levelowner, sizeof(TInt));
   327 			TEST_KERRNONE(r);
   328 			break;
   329 			}
   330 
   331 		case RPrmIf::EControlGetTotalNumberOfResources:
   332 			{
   333 			if (!iClientId)
   334 				{
   335 				return KErrNotReady;
   336 				}
   337 			TUint nores;
   338 			r = PowerResourceManager::GetNumResourcesInUseByClient(iClientId, 0, nores);
   339 			TEST_KERRNONE(r);
   340 			if (r)
   341 				{
   342 				return r;
   343 				}
   344 			r = Kern::ThreadRawWrite(iUserThread, a1, (TAny*) &nores, sizeof(TUint));
   345 			TEST_KERRNONE(r);
   346 			break;
   347 			}
   348 
   349 #ifdef PRM_ENABLE_EXTENDED_VERSION
   350 		case RPrmIf::EControlGetResourceDependencies:
   351 			{
   352 			if (!iClientId)
   353 				{
   354 				return KErrNotReady;
   355 				}
   356 			// Get the resource information from the PRM
   357 			TUint numres;
   358 			r = PowerResourceManager::GetNumDependentsForResource(iClientId, (TUint) a1, numres);
   359 			TEST_KERRNONE(r);
   360 			if (r)
   361 				{
   362 				return r;
   363 				}
   364 
   365 			// Create a descriptor with the list of dependencies
   366 			HBuf* depdes;
   367 			depdes = HBuf::New(sizeof(SResourceDependencyInfo) * numres);
   368 			TEST(depdes != NULL);
   369 			if (depdes == NULL)
   370 				{
   371 				return KErrNoMemory;
   372 				}
   373 
   374 			TUint numres2 = numres;
   375 			r = PowerResourceManager::GetDependentsIdForResource(iClientId, (TUint) a1, (TAny*) depdes, numres2);
   376 			TEST_KERRNONE(r);
   377 			TEST(numres == numres2);
   378 			
   379 			// Copy the descriptor contents to the user-side descriptor
   380 			r = Kern::ThreadDesWrite(iUserThread, a2, *depdes, 0);
   381 			TEST_KERRNONE(r);
   382 			delete depdes;
   383 			break;
   384 			}
   385 #endif // PRM_ENABLE_EXTENDED_VERSION
   386 		}
   387 	return r;
   388 	}
   389 
   390 TInt DPrmIfChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny *a1, TAny *a2)
   391 	{
   392 	TInt r = KErrNotSupported;
   393 	switch (aReqNo)
   394 		{
   395 		case RPrmIf::ERequestChangeResourceStateAndGetState:
   396 			{
   397 			if (!iClientId)
   398 				{
   399 				return KErrNotReady;
   400 				}
   401 			TTestResourceStateBuf args;
   402 			r = Kern::ThreadDesRead(iUserThread, a1, args, 0);
   403 			TEST_KERRNONE(r);
   404 			if (r)
   405 				{
   406 				return r;
   407 				}
   408 			NFastSemaphore sem;
   409 			NKern::FSSetOwner(&sem, (NThreadBase*) NKern::CurrentThread());
   410 			TPowerResourceCb cbfn(&TestCallbackFunction, (TAny*) &sem, /*iDfcQ*/ Kern::DfcQue0(), KMaxDfcPriority - 2);
   411 			// Change the state of the resource (asynchronous call)
   412 			r = PowerResourceManager::ChangeResourceState(iClientId, args().iResourceId, args().iNewState, &cbfn);
   413 			TEST_KERRNONE(r);
   414 			if (r)
   415 				{
   416 				return r;
   417 				}
   418 			// Retrieve the intermediate state of the resource
   419 			TInt state;
   420 			TInt levelowner;
   421 			r = PowerResourceManager::GetResourceState(iClientId, args().iResourceId, EFalse, state, levelowner);
   422 			TEST_KERRNONE(r);
   423 			if (r)
   424 				{
   425 				return r;
   426 				}
   427 			r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt));
   428 			TEST_KERRNONE(r);
   429 			if (r)
   430 				{
   431 				return r;
   432 				}
   433 			// Wait for the callback function
   434 			NKern::FSWait(&sem);
   435 			Kern::RequestComplete(iUserThread, aStatus, r);
   436 			break;
   437 			}
   438 		}
   439 	return r;
   440 	}
   441 
   442 //---------------------------------------------------------------------------
   443 
   444 //
   445 // Callback function for Latency Tests
   446 //
   447 void TestCallbackFunction(TUint /* aClientId */,
   448 						  TUint /* aResourceId */,
   449 						  TInt  /* aLevel */,
   450 						  TInt  /* aLevelOwnerId */,
   451 						  TInt  /* aResult */,
   452 						  TAny* aSem)
   453 	{
   454 	if (!aSem)
   455 		{
   456 		return;
   457 		}
   458 	NKern::FSSignal((NFastSemaphore*) aSem);
   459 	}
   460 
   461 //
   462 // This function is called during kernel initialisation. It registers a client
   463 // on the PRM in order to take ownership of the Single-User resources before
   464 // anyone else does.
   465 //
   466 static void InitExtension(TAny*)
   467 	{
   468 	TInt r;	
   469 
   470 	// Get the overall number of resources
   471 	TUint nores;
   472 	r = PowerResourceManager::GetNumResourcesInUseByClient(DPrmIfChannel::KernelExtensionClientId, 0, nores);
   473 	TEST_KERRNONE(r);
   474 	if (r)
   475 		{
   476 		return;
   477 		}
   478 
   479 	// Get hold of all of the resources by setting their state to the default level
   480 	TInt i;
   481 	for (i = 0; i < (TInt) nores; i++)
   482 		{
   483 		TPowerResourceInfoBuf01 res;
   484 		res.Zero();
   485 		r = PowerResourceManager::GetResourceInfo(DPrmIfChannel::KernelExtensionClientId, i + 1, (TAny*) &res);
   486 		TEST_KERRNONE(r);
   487 		if (r)
   488 			{
   489 			return;
   490 			}
   491 		r = PowerResourceManager::ChangeResourceState(DPrmIfChannel::KernelExtensionClientId, i + 1, res().iDefaultLevel);
   492 		TEST_KERRNONE(r);
   493 		if (r)
   494 			{
   495 			return;
   496 			}
   497 		}
   498 	TUint resinuse;
   499 	r = PowerResourceManager::GetNumResourcesInUseByClient(DPrmIfChannel::KernelExtensionClientId, DPrmIfChannel::KernelExtensionClientId, resinuse);
   500 	TEST_KERRNONE(r);
   501 	TEST(resinuse == nores);
   502 	}
   503 
   504 static TDfc InitExtensionDfc(&InitExtension, NULL, Kern::SvMsgQue(), KMaxDfcPriority - 2); // Priority lower than the Resource Controller (KMaxDfcPriority - 1)
   505 
   506 #ifndef RESOURCE_MANAGER_SIMULATED_PSL
   507 _LIT8(KTestKExtClientName, "KEXTC");
   508 DECLARE_STANDARD_EXTENSION()
   509 	{
   510 	// Register the initial PRM client (kernel will crash if this fails)
   511 	TUint clientid;
   512 	TInt r = PowerResourceManager::RegisterClient(clientid, KTestKExtClientName);
   513 	TEST_KERRNONE(r);
   514 	if (r)
   515 		{
   516 		return r;
   517 		}
   518 	DPrmIfChannel::KernelExtensionClientId = clientid;
   519 	// Queue the DFC call to take control of all the resources
   520 	InitExtensionDfc.Enque();
   521 	return KErrNone;
   522 	}
   523 
   524 DECLARE_EXTENSION_LDD()
   525 	{
   526 	return new DPrmIfDevice;
   527 	}
   528 #else
   529 DECLARE_STANDARD_LDD()
   530 	{
   531 	TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation();
   532 	if (r != KErrNone)
   533 		{
   534 		return NULL;
   535 		}
   536 	return new DPrmIfDevice;
   537 	}
   538 #endif