diff -r 000000000000 -r a41df078684a kerneltest/e32test/resourceman/acctst/d_prmacctst.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/resourceman/acctst/d_prmacctst.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,538 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include "d_prmacctst.h" +#ifdef RESOURCE_MANAGER_SIMULATED_PSL +#include "../resourceman_psl/rescontrol_psl.h" +#endif // RESOURCE_MANAGER_SIMULATED_PSL + +#define TEST_KERRNONE(x) { TInt _r = (x); if (_r != KErrNone) \ + Kern::Printf("Test failed: %s line %d error %d", __FILE__, __LINE__, _r); } +#define TEST(x) { if (!(x)) Kern::Printf("Test failed: %s line %d", __FILE__, __LINE__); } + +_LIT(KTestDfcQueBaseName, "PrmIfDfc"); +const TInt KTestDfcQuePrority = KMaxDfcPriority - 1; + +//--------------------------------------------------------------------------- + +class DPrmIfDevice : public DLogicalDevice + { +public: + DPrmIfDevice(); + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + }; + +//--------------------------------------------------------------------------- + +class DPrmIfChannel : public DLogicalChannel + { +public: + DPrmIfChannel(); + ~DPrmIfChannel(); +protected: + virtual void HandleMsg(TMessageBase* aMsg); + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); +private: + TInt DoControl(TInt aReqNo, TAny *a1, TAny *a2); + TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny *a1, TAny *a2); + void Shutdown(); + +public: + static TUint KernelExtensionClientId; +private: + DThread* iUserThread; + TUint iClientId; + HBuf* iClientName; + }; + +TUint DPrmIfChannel::KernelExtensionClientId = 0; + +void TestCallbackFunction(TUint /* aClientId */, + TUint /* aResourceId */, + TInt /* aLevel */, + TInt /* aLevelOwnerId */, + TInt /* aResult */, + TAny* aSem); + +//--------------------------------------------------------------------------- + +DPrmIfDevice::DPrmIfDevice() + { + } + +TInt DPrmIfDevice::Install() + { + return SetName(&KPrmIfLddName); + } + +void DPrmIfDevice::GetCaps(TDes8& /* aDes */) const + { + // Not used but required as DLogicalDevice::GetCaps is pure virtual + } + +TInt DPrmIfDevice::Create(DLogicalChannelBase*& aChannel) + { + aChannel = new DPrmIfChannel; + return aChannel ? KErrNone : KErrNoMemory; + } + +//--------------------------------------------------------------------------- + +DPrmIfChannel::DPrmIfChannel() + { + iUserThread = &Kern::CurrentThread(); + ((DObject*) iUserThread)->Open(); + } + +DPrmIfChannel::~DPrmIfChannel() + { + if(iDfcQ) + ((TDynamicDfcQue*)iDfcQ)->Destroy(); + // Close our reference on the client thread + Kern::SafeClose((DObject*&)iUserThread,NULL); + } + +void DPrmIfChannel::HandleMsg(TMessageBase *aMsg) + { + TThreadMessage& m = *(TThreadMessage*) aMsg; + TInt id = m.iValue; + + if (id == (TInt) ECloseMsg) + { + m.Complete(KErrNone, EFalse); + return; + } + else if (id == KMaxTInt) + { + // DoCancel + m.Complete(KErrNone, ETrue); + return; + } + else if (id < 0) + { + // DoRequest + TRequestStatus* pS = (TRequestStatus*) m.Ptr0(); + TInt r = DoRequest(~id, pS, m.Ptr1(), m.Ptr2()); + if (r != KErrNone) + { + Kern::RequestComplete(iUserThread, pS, r); + } + m.Complete(KErrNone, ETrue); + } + else + { + // DoControl + TInt r = DoControl(id, m.Ptr0(), m.Ptr1()); + if(r != KErrCompletion) + { + m.Complete(r, ETrue); + } + } + } + +TInt DPrmIfChannel::DoCreate(TInt /* aUnit */, const TDesC8* /* aInfo */, const TVersion& /* aVer */) + { + TDynamicDfcQue* dfcQ; + TInt r = Kern::DynamicDfcQCreate(dfcQ, KTestDfcQuePrority, KTestDfcQueBaseName); + TEST_KERRNONE(r); + iDfcQ = dfcQ; + if (r != KErrNone) + { + return r; + } + SetDfcQ(iDfcQ); + iMsgQ.Receive(); + return KErrNone; + } + +TInt DPrmIfChannel::DoControl(TInt aReqNo, TAny *a1, TAny *a2) + { + TInt r = KErrNotSupported; + switch (aReqNo) + { + case RPrmIf::EControlOpenClient: + { + if (iClientId) + { + return KErrAlreadyExists; + } + TBuf8<80> clientName; + r = PowerResourceManager::GetClientName((TUint) a1, (TUint) a1, clientName); + TEST_KERRNONE(r); + if (r == KErrNone) + iClientId = (TUint) a1; + break; + } + + case RPrmIf::EControlGetKernelExtClientId: + { + r = Kern::ThreadRawWrite(iUserThread, a1, &KernelExtensionClientId, sizeof(TUint)); + TEST_KERRNONE(r); + break; + } + + case RPrmIf::EControlRegisterClient: + { + if (iClientId) + { + return KErrAlreadyExists; + } + iClientName = HBuf::New(KNameMaxLength); + r = Kern::ThreadDesRead(iUserThread, a1, *iClientName, 0); + TEST_KERRNONE(r); + if (r) + { + return r; + } + r = PowerResourceManager::RegisterClient(iClientId, *iClientName); + TEST_KERRNONE(r); + break; + } + + case RPrmIf::EControlDeRegisterClient: + { + if (!iClientId) + { + return KErrNotReady; + } + r = PowerResourceManager::DeRegisterClient(iClientId); + if (r == KErrNone) + { + if (iClientId == KernelExtensionClientId) + { + // Set it to 0 so it cannot be re-opened + KernelExtensionClientId = 0; + } + delete iClientName; + iClientId = 0; + } + break; + } + + case RPrmIf::EControlGetInfoOnResourcesInUseByClient: + { + if (!iClientId) + { + return KErrNotReady; + } + TUint nores; + r = PowerResourceManager::GetNumResourcesInUseByClient(iClientId, (TUint) a1, nores); + TEST_KERRNONE(r); + if (r) + { + return r; + } + if (nores > 0) + { + HBuf* resinfo; + resinfo = HBuf::New(nores * sizeof(TResInfo)); + TEST(resinfo != NULL); + if (resinfo == NULL) + { + return KErrNoMemory; + } + r = PowerResourceManager::GetInfoOnResourcesInUseByClient(iClientId, (TUint) a1, nores, (TAny*) resinfo); + TEST_KERRNONE(r); + if (r) + { + delete resinfo; + return r; + } + r = Kern::ThreadDesWrite(iUserThread, a2, *resinfo, 0); + TEST_KERRNONE(r); + delete resinfo; + } + break; + } + + case RPrmIf::EControlChangeResourceState: + { + if (!iClientId) + { + return KErrNotReady; + } + r = PowerResourceManager::ChangeResourceState(iClientId, (TUint) a1, (TInt) a2); + break; + } + + case RPrmIf::EControlGetResourceState: + { + if (!iClientId) + { + return KErrNotReady; + } + TInt state; + TInt levelowner; + r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, EFalse, state, levelowner); + TEST_KERRNONE(r); + if (r) + { + return r; + } + r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt)); + TEST_KERRNONE(r); + break; + } + + case RPrmIf::EControlGetResourceStateCached: + { + if (!iClientId) + { + return KErrNotReady; + } + TInt state; + TInt levelowner; + r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, ETrue, state, levelowner); + TEST_KERRNONE(r); + if (r) + { + return r; + } + r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt)); + TEST_KERRNONE(r); + break; + } + + case RPrmIf::EControlGetLevelOwner: + { + if (!iClientId) + { + return KErrNotReady; + } + TInt state; + TInt levelowner; + r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, EFalse, state, levelowner); + TEST_KERRNONE(r); + if (r) + { + return r; + } + r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &levelowner, sizeof(TInt)); + TEST_KERRNONE(r); + break; + } + + case RPrmIf::EControlGetTotalNumberOfResources: + { + if (!iClientId) + { + return KErrNotReady; + } + TUint nores; + r = PowerResourceManager::GetNumResourcesInUseByClient(iClientId, 0, nores); + TEST_KERRNONE(r); + if (r) + { + return r; + } + r = Kern::ThreadRawWrite(iUserThread, a1, (TAny*) &nores, sizeof(TUint)); + TEST_KERRNONE(r); + break; + } + +#ifdef PRM_ENABLE_EXTENDED_VERSION + case RPrmIf::EControlGetResourceDependencies: + { + if (!iClientId) + { + return KErrNotReady; + } + // Get the resource information from the PRM + TUint numres; + r = PowerResourceManager::GetNumDependentsForResource(iClientId, (TUint) a1, numres); + TEST_KERRNONE(r); + if (r) + { + return r; + } + + // Create a descriptor with the list of dependencies + HBuf* depdes; + depdes = HBuf::New(sizeof(SResourceDependencyInfo) * numres); + TEST(depdes != NULL); + if (depdes == NULL) + { + return KErrNoMemory; + } + + TUint numres2 = numres; + r = PowerResourceManager::GetDependentsIdForResource(iClientId, (TUint) a1, (TAny*) depdes, numres2); + TEST_KERRNONE(r); + TEST(numres == numres2); + + // Copy the descriptor contents to the user-side descriptor + r = Kern::ThreadDesWrite(iUserThread, a2, *depdes, 0); + TEST_KERRNONE(r); + delete depdes; + break; + } +#endif // PRM_ENABLE_EXTENDED_VERSION + } + return r; + } + +TInt DPrmIfChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny *a1, TAny *a2) + { + TInt r = KErrNotSupported; + switch (aReqNo) + { + case RPrmIf::ERequestChangeResourceStateAndGetState: + { + if (!iClientId) + { + return KErrNotReady; + } + TTestResourceStateBuf args; + r = Kern::ThreadDesRead(iUserThread, a1, args, 0); + TEST_KERRNONE(r); + if (r) + { + return r; + } + NFastSemaphore sem; + NKern::FSSetOwner(&sem, (NThreadBase*) NKern::CurrentThread()); + TPowerResourceCb cbfn(&TestCallbackFunction, (TAny*) &sem, /*iDfcQ*/ Kern::DfcQue0(), KMaxDfcPriority - 2); + // Change the state of the resource (asynchronous call) + r = PowerResourceManager::ChangeResourceState(iClientId, args().iResourceId, args().iNewState, &cbfn); + TEST_KERRNONE(r); + if (r) + { + return r; + } + // Retrieve the intermediate state of the resource + TInt state; + TInt levelowner; + r = PowerResourceManager::GetResourceState(iClientId, args().iResourceId, EFalse, state, levelowner); + TEST_KERRNONE(r); + if (r) + { + return r; + } + r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt)); + TEST_KERRNONE(r); + if (r) + { + return r; + } + // Wait for the callback function + NKern::FSWait(&sem); + Kern::RequestComplete(iUserThread, aStatus, r); + break; + } + } + return r; + } + +//--------------------------------------------------------------------------- + +// +// Callback function for Latency Tests +// +void TestCallbackFunction(TUint /* aClientId */, + TUint /* aResourceId */, + TInt /* aLevel */, + TInt /* aLevelOwnerId */, + TInt /* aResult */, + TAny* aSem) + { + if (!aSem) + { + return; + } + NKern::FSSignal((NFastSemaphore*) aSem); + } + +// +// This function is called during kernel initialisation. It registers a client +// on the PRM in order to take ownership of the Single-User resources before +// anyone else does. +// +static void InitExtension(TAny*) + { + TInt r; + + // Get the overall number of resources + TUint nores; + r = PowerResourceManager::GetNumResourcesInUseByClient(DPrmIfChannel::KernelExtensionClientId, 0, nores); + TEST_KERRNONE(r); + if (r) + { + return; + } + + // Get hold of all of the resources by setting their state to the default level + TInt i; + for (i = 0; i < (TInt) nores; i++) + { + TPowerResourceInfoBuf01 res; + res.Zero(); + r = PowerResourceManager::GetResourceInfo(DPrmIfChannel::KernelExtensionClientId, i + 1, (TAny*) &res); + TEST_KERRNONE(r); + if (r) + { + return; + } + r = PowerResourceManager::ChangeResourceState(DPrmIfChannel::KernelExtensionClientId, i + 1, res().iDefaultLevel); + TEST_KERRNONE(r); + if (r) + { + return; + } + } + TUint resinuse; + r = PowerResourceManager::GetNumResourcesInUseByClient(DPrmIfChannel::KernelExtensionClientId, DPrmIfChannel::KernelExtensionClientId, resinuse); + TEST_KERRNONE(r); + TEST(resinuse == nores); + } + +static TDfc InitExtensionDfc(&InitExtension, NULL, Kern::SvMsgQue(), KMaxDfcPriority - 2); // Priority lower than the Resource Controller (KMaxDfcPriority - 1) + +#ifndef RESOURCE_MANAGER_SIMULATED_PSL +_LIT8(KTestKExtClientName, "KEXTC"); +DECLARE_STANDARD_EXTENSION() + { + // Register the initial PRM client (kernel will crash if this fails) + TUint clientid; + TInt r = PowerResourceManager::RegisterClient(clientid, KTestKExtClientName); + TEST_KERRNONE(r); + if (r) + { + return r; + } + DPrmIfChannel::KernelExtensionClientId = clientid; + // Queue the DFC call to take control of all the resources + InitExtensionDfc.Enque(); + return KErrNone; + } + +DECLARE_EXTENSION_LDD() + { + return new DPrmIfDevice; + } +#else +DECLARE_STANDARD_LDD() + { + TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation(); + if (r != KErrNone) + { + return NULL; + } + return new DPrmIfDevice; + } +#endif