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) 1998-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\misc\t_asid.cpp
//
//
#define __E32TEST_EXTENSION__
#include <e32test.h>
#include <e32svr.h>
#include <u32std.h>
#include "t_asid.h"
#include "d_asid.h"
#define TEST_R(r, e) if (!(e)) {RDebug::Printf("Failure at line %d, r = %d", __LINE__, r); return r; }
_LIT(KDummyProcessName,"T_ASID_DUMMY");
RTest test(_L("T_ASID"));
const TUint KMaxAsids = 256; // On arm and current version of FMM has maximum of 256 active processes at once.
const TUint KLeakedProcesses = KMaxAsids<<1;
void TestMaxAsids()
{
test.Printf(_L("Attempt to load > %d zombie processes\n"), KMaxAsids);
RProcess* processes = new RProcess[KLeakedProcesses];
TUint i = 0;
for (; i < KLeakedProcesses; i++)
{
test_KErrNone(processes[i].Create(KDummyProcessName, KNullDesC));
TRequestStatus s;
processes[i].Logon(s);
test_Equal(KRequestPending, s.Int());
processes[i].Resume();
User::WaitForRequest(s);
if (processes[i].ExitType()!=EExitKill || processes[i].ExitReason()!=KErrNone)
{
TExitCategoryName aExitCategory = processes[i].ExitCategory();
test.Printf(_L("Exit %d,%d,%S\n"),processes[i].ExitType(),processes[i].ExitReason(),&aExitCategory);
test(0);
}
}
// Clean up the process handles here.
for (i = 0; i < KLeakedProcesses; i++)
processes[i].Close();
delete[] processes;
}
TInt TestIpcThread(TAny*)
{
// Start a server for zombie to connect to.
RServer2 ipcServer;
TInt r = ipcServer.CreateGlobal(KAsidIpcServerName);
TEST_R(r, r == KErrNone);
RMessage2 ipcMessage;
for (TUint i = 0; i < 300; i++)
{
// Start the process.
RProcess zombie;
TInt r = zombie.Create(KDummyProcessName, KAsidIpcServerName);
TEST_R(r, r == KErrNone);
TRequestStatus s;
zombie.Logon(s);
TEST_R(s.Int(), s.Int() == KRequestPending);
zombie.Resume();
// Wait for the connect and ipc message from the zombie
ipcServer.Receive(ipcMessage);
TEST_R(ipcMessage.Function(), ipcMessage.Function() == EConnect);
ipcMessage.Complete(KErrNone);
ipcServer.Receive(ipcMessage);
TEST_R(ipcMessage.Function(), ipcMessage.Function() == EIpcData);
TUint8 array1[KAsidDesLen];
memset(array1, KAsidValue, KAsidDesLen);
TPtr8 buf1(array1, KAsidDesLen, KAsidDesLen);
TUint8 array[KAsidDesLen];
TPtr8 buf(array, KAsidDesLen);
test_Equal(KErrNone, ipcMessage.Read(0, buf));
r = ipcMessage.Read(0, buf);
TEST_R(r, r == KErrNone);
r = buf.Compare(buf1);
TEST_R(r, r == 0);
ipcMessage.Complete(KErrNone);
// Try to read from the client while it is exiting.
ipcServer.Receive(ipcMessage);
TEST_R(ipcMessage.Function(), ipcMessage.Function() == EIpcData);
User::After(5*i);
r = ipcMessage.Read(0, buf);
//RDebug::Printf("%d", r);
// Wait for client to exit.
User::WaitForRequest(s);
TEST_R(s.Int(), s.Int() == KErrNone);
ipcServer.Receive(ipcMessage); // Clear out the disconnect message.
TEST_R(ipcMessage.Function(), ipcMessage.Function() == EDisConnect);
ipcMessage.Complete(KErrNone);
zombie.Close();
}
ipcServer.Close();
return KErrNone;
}
TInt TestDesThread(TAny*)
{
RAsidLdd asidLdd;
TInt r = asidLdd.Open();
TEST_R(r, r == KErrNone);
RMessage2 desMessage;
RServer2 desServer;
// Start a server for zombie to connect to.
r = desServer.CreateGlobal(KAsidDesServerName);
TEST_R(r, r == KErrNone);
for (TUint i = 0; i < 300; i++)
{
// Start the process.
RProcess zombie;
r = zombie.Create(KDummyProcessName, KAsidDesServerName);
TEST_R(r, r == KErrNone);
TRequestStatus s;
zombie.Logon(s);
TEST_R(s.Int(), s.Int() == KRequestPending);
zombie.Resume();
// Wait for the connect and des message from the zombie
desServer.Receive(desMessage);
TEST_R(desMessage.Function(), desMessage.Function() == EConnect);
desMessage.Complete(KErrNone);
desServer.Receive(desMessage);
TEST_R(desMessage.Function(), desMessage.Function() == EDesData);
TAny* desPtr = (TAny*)desMessage.Ptr0();
TAny* threadPtr = (TAny*)desMessage.Ptr1();
// Open a handle on the client's thread to stop it being deleted.
r = asidLdd.OpenThread(threadPtr);
TEST_R(r, r == KErrNone);
SDesHeader desHdr;
desHdr.iDes = desPtr;
r = asidLdd.ReadDesHeader(threadPtr, desHdr);
TEST_R(r, r == KErrNone);
TEST_R(desHdr.iLength, desHdr.iLength == KAsidDesLen);
TEST_R(desHdr.iMaxLength, desHdr.iMaxLength == KAsidDesLen);
desMessage.Complete(KErrNone);
// Wait for further des message from client.
desServer.Receive(desMessage);
TEST_R(desMessage.Function(), desMessage.Function() == EDesData);
desPtr = (TAny*)desMessage.Ptr0();
TEST_R((TInt)desMessage.Ptr1(), (TInt)desMessage.Ptr1() == (TInt)threadPtr);
// Try to read descriptor header from the client while it is exiting.
TInt r = asidLdd.ReadDesHeader(threadPtr, desHdr);
User::After(5*i);
//RDebug::Printf("%d", r);
if (r == KErrNone)
{
TEST_R(desHdr.iLength, desHdr.iLength == KAsidDesLen);
TEST_R(desHdr.iMaxLength, desHdr.iMaxLength == KAsidDesLen);
}
// Wait for client to exit.
User::WaitForRequest(s);
TEST_R(s.Int(), s.Int() == KErrNone);
desServer.Receive(desMessage); // Clear out the disconnect message.
TEST_R(desMessage.Function(), desMessage.Function() == EDisConnect);
desMessage.Complete(KErrNone);
// Close handles in client process and thread.
r = asidLdd.CloseThread();
TEST_R(r, r == KErrNone);
zombie.Close();
}
desServer.Close();
asidLdd.Close();
return KErrNone;
}
GLDEF_C TInt E32Main()
{
test.Title();
test.Start(_L("Test zombie processes release their ASIDs"));
// Get memory model.
if ((UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL)&EMemModelTypeMask) < EMemModelTypeFlexible)
{
test.Printf(_L("SKIPPING TEST - Older memory models don't release ASIDs from zombie processes\n"));
test.End();
return KErrNone;
}
TestMaxAsids();
test.Next(_L("Test ipc message copy to a zombie process"));
test_KErrNone(TestIpcThread(NULL));
TestMaxAsids();
test.Next(_L("Test reading descriptor header from a zombie process"));
test_KErrNone(TestDesThread(NULL));
TestMaxAsids();
test.Next(_L("Test ipc and des header to zombie processes concurrently"));
RThread ipcThread;
RThread desThread;
ipcThread.Create(KNullDesC, TestIpcThread, 0x2000, NULL, NULL);
desThread.Create(KNullDesC, TestDesThread, 0x2000, NULL, NULL);
TRequestStatus ipcStatus;
TRequestStatus desStatus;
ipcThread.Logon(ipcStatus);
desThread.Logon(desStatus);
ipcThread.Resume();
desThread.Resume();
// Wait for threads to complete.
User::WaitForRequest(ipcStatus);
test_KErrNone(ipcStatus.Int());
User::WaitForRequest(desStatus);
test_KErrNone(desStatus.Int());
TestMaxAsids();
test.End();
return KErrNone;
}