--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/resourceman/acctst/d_prmacctst.cpp Thu Dec 17 09:24:54 2009 +0200
@@ -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 <kernel/kernel.h>
+#include <drivers/resourceman.h>
+#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