Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 2005-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:
// e32test\emi\d_emitest.cpp
//
//
#include <kernel/kern_priv.h>
#include "d_emitest.h"
#include "d_emitest_dev.h"
#include <kernel/emi.h>
//
// DEMITestFactory
//
/*
Standard export function for LDDs. This creates a DLogicalDevice derived object,
in this case, our DEMITestFactory
*/
DECLARE_STANDARD_LDD()
{
return new DEMITestFactory;
}
DEMITestFactory::DEMITestFactory()
{
}
DEMITestFactory::~DEMITestFactory()
{
}
/*
Second stage constructor for DEMITestFactory.
This must at least set a name for the driver object.
@return KErrNone or standard error code.
*/
TInt DEMITestFactory::Install()
{
return SetName(&KEMITestName);
}
/*
Return the drivers capabilities.
Called in the response to an RDevice::GetCaps() request.
The thread is in a critical section.
@param aDes Descriptor to write capabilities information into
*/
void DEMITestFactory::GetCaps(TDes8&) const
{
}
/*
Called by the kernel's device driver framework to create a Logical Channel.
This is called in the context of the user thread (client) which requested the creation of a Logical Channel
(E.g. through a call to RBusLogicalChannel::DoCreate)
The thread is in a critical section.
@param aChannel Set to point to the created Logical Channel
@return KErrNone or standard error code.
*/
TInt DEMITestFactory::Create(DLogicalChannelBase*& aChannel)
{
aChannel=new DEMITestChannel;
if(!aChannel)
return KErrNoMemory;
return KErrNone;
}
//
// Logical Channel
//
DEMITestChannel::DEMITestChannel()
: iTagMaskDFC(TagMaskDFC,NULL,1)
{
// Get pointer to client threads DThread object
iClient=&Kern::CurrentThread();
// Open a reference on client thread so it's control block can't dissapear until
// this driver has finished with it.
((DObject*)iClient)->Open();
}
DEMITestChannel::~DEMITestChannel()
{
// Stop EMI, incase it wannt stopped manually.
EMI::TaskEventLogging(EFalse,0,NULL,NULL);
EMI::SetMask(0);
// Close our reference on the client thread
Kern::SafeClose((DObject*&)iClient,NULL);
}
/*
Second stage constructor called by the kernel's device driver framework.
This is called in the context of the user thread (client) which requested the creation of a Logical Channel
(E.g. through a call to RBusLogicalChannel::DoCreate)
The thread is in a critical section.
@param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
@param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
@param aVer The version argument supplied by the client to RBusLogicalChannel::DoCreate
@return KErrNone or standard error code.
*/
TInt DEMITestChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion&)
{
iTagMaskDFC.SetDfcQ(Kern::DfcQue0());
return KErrNone;
}
/*
Normal test monitors
*/
TInt MyThreadStartMonitor(NThread* aNThread)
{
TTaskEventRecord rec;
rec.iType=128;
rec.iPrevious=((TInt*) aNThread)+1; // This stops the event getting killed on thread exit.
// This means there is no garantee the thread will still exist when
// the record is read. This is only safe here as the test code never
// attempts to derefrance this pointer.
EMI::AddTaskEvent(rec);
return 0;
}
void MyThreadExitMonitor(NThread* aNThread)
{
TTaskEventRecord rec;
rec.iType=129;
rec.iPrevious=aNThread;
EMI::AddTaskEvent(rec);
}
/*
Stress test monitors
Vems = 1: Passed.
0: No monitors called.
-1: Wrong Exit monitor callled.
-2: Exit call before StartMonitor
-3: Jibberish VEMs value. (or anything ending 5-9)
-4: Exit called multiple times, 1st time ok.
<-9: Exit called multiple times. See last digit for status 1st time.
Stops couting after -1000, where its clearly very sick!
*/
TInt SoakStartMonitor1(NThread* aNThread)
{
EMI::SetThreadVemsData(aNThread,(TAny*)1000);
return 0;
}
TInt SoakStartMonitor2(NThread* aNThread)
{
EMI::SetThreadVemsData(aNThread,(TAny*)2000);
return 0;
}
inline void SoakExitMonitor(NThread* aNThread, TInt aOwner)
{
TInt val = (TInt) EMI::GetThreadVemsData(aNThread);
if (val>-1)
{
TInt notOwner = (aOwner==1000?2000:1000);
if (val==aOwner)
EMI::SetThreadVemsData(aNThread,(TAny*)1);
else if (val==notOwner)
EMI::SetThreadVemsData(aNThread,(TAny*)-1);
else if (val==0)
EMI::SetThreadVemsData(aNThread,(TAny*)-2);
else if (val==1)
EMI::SetThreadVemsData(aNThread,(TAny*)-4);
else
EMI::SetThreadVemsData(aNThread,(TAny*)-3);
}
else
{
if (val>-1000)
EMI::SetThreadVemsData(aNThread,(TAny*)(val-10));
else
EMI::SetThreadVemsData(aNThread,(TAny*)val);
}
}
void SoakExitMonitor1(NThread* aNThread)
{
SoakExitMonitor(aNThread,1000);
}
void SoakExitMonitor2(NThread* aNThread)
{
SoakExitMonitor(aNThread,2000);
}
/*
Process synchronous requests
*/
TInt DEMITestChannel::Request(TInt aFunction, TAny* a1, TAny* a2)
{
TInt r=KErrNotSupported;
TTaskEventRecord rec;
switch (aFunction)
{
case REMITest::ETaskEventLogging:
{
NKern::ThreadEnterCS();
TMonitors mon = (TMonitors) ((TInt)a1 >> 1);
TBool logging = (TBool) ((TInt)a1 & 1);
switch (mon)
{
case ENone: r = EMI::TaskEventLogging(logging,(TInt) a2,NULL,NULL);
break;
case ENormal: r = EMI::TaskEventLogging(logging,(TInt) a2,&MyThreadStartMonitor,&MyThreadExitMonitor);
break;
case EStressFirst:r = EMI::TaskEventLogging(logging,(TInt) a2,SoakStartMonitor1,SoakExitMonitor1);
break;
case EStressSecond:r = EMI::TaskEventLogging(logging,(TInt) a2,SoakStartMonitor2,SoakExitMonitor2);
}
NKern::ThreadLeaveCS();
return r;
}
case REMITest::EGetTaskEvent:
r = (TInt) EMI::GetTaskEvent(rec);
if (r)
kumemput(a1,&rec,sizeof(TTaskEventRecord));
return r;
case REMITest::EAddTaskEvent:
kumemget(&rec,a1,sizeof(TTaskEventRecord));
return (TInt) EMI::AddTaskEvent(rec);
case REMITest::EGetIdleThread:
return (TInt) EMI::GetIdleThread();
case REMITest::EGetSigmaThread:
return (TInt) EMI::GetSigmaThread();
case REMITest::ESetVEMSData:
EMI::SetThreadVemsData((NThread*) a1,a2);
return KErrNone;
case REMITest::EGetVEMSData:
return (TInt) EMI::GetThreadVemsData((NThread*) a1);
case REMITest::ESetThreadLoggable:
EMI::SetThreadLoggable((NThread*) a1,(TBool) a2);
return KErrNone;
case REMITest::EGetThreadLoggable:
return (TInt) EMI::GetThreadLoggable((NThread*) a1);
case REMITest::ESetThreadTag:
EMI::SetThreadTag((NThread*) a1,(TUint32) a2);
return KErrNone;
case REMITest::EGetThreadTag:
return (TInt) EMI::GetThreadTag((NThread*) a1);
case REMITest::ESetMask:
EMI::SetMask((TInt) a1);
return KErrNone;
case REMITest::EGetMask:
return EMI::GetMask();
case REMITest::ESetDFC:
EMI::SetDfc(&iTagMaskDFC, 0);
return KErrNone;
case REMITest::ESetState:
EMI::SetState((TInt) a1);
return KErrNone;
case REMITest::EGetState:
return EMI::GetState();
case REMITest::EGetNThread:
{
DThread* myThread;
TInt myNThread;
NKern::LockSystem();
myThread = (DThread* ) Kern::CurrentThread().ObjectFromHandle((TInt)a1,EThread);
myNThread= (TInt) (myThread==NULL?NULL:&myThread->iNThread);
NKern::UnlockSystem();
return myNThread;
}
case REMITest::EAfterIdle:
EMI::AfterIdle((TInt) a1);
return KErrNone;
default:
return KErrNotSupported;
}
}
/*
DFC callback which gets triggered when the EMI tag anded with thread mask is true.
Sets EMI state to be the value returned from GetDfcTriggerTag.
*/
void DEMITestChannel::TagMaskDFC(TAny*)
{
EMI::SetState(EMI::GetDfcTriggerTag());
EMI::SetMask(0);
}