First public contribution.
1 // Copyright (c) 1998-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\misc\t_asid.cpp
17 #define __E32TEST_EXTENSION__
25 #define TEST_R(r, e) if (!(e)) {RDebug::Printf("Failure at line %d, r = %d", __LINE__, r); return r; }
27 _LIT(KDummyProcessName,"T_ASID_DUMMY");
29 RTest test(_L("T_ASID"));
31 const TUint KMaxAsids = 256; // On arm and current version of FMM has maximum of 256 active processes at once.
32 const TUint KLeakedProcesses = KMaxAsids<<1;
36 test.Printf(_L("Attempt to load > %d zombie processes\n"), KMaxAsids);
37 RProcess* processes = new RProcess[KLeakedProcesses];
39 for (; i < KLeakedProcesses; i++)
41 test_KErrNone(processes[i].Create(KDummyProcessName, KNullDesC));
43 processes[i].Logon(s);
44 test_Equal(KRequestPending, s.Int());
45 processes[i].Resume();
46 User::WaitForRequest(s);
47 if (processes[i].ExitType()!=EExitKill || processes[i].ExitReason()!=KErrNone)
49 TExitCategoryName aExitCategory = processes[i].ExitCategory();
50 test.Printf(_L("Exit %d,%d,%S\n"),processes[i].ExitType(),processes[i].ExitReason(),&aExitCategory);
54 // Clean up the process handles here.
55 for (i = 0; i < KLeakedProcesses; i++)
61 TInt TestIpcThread(TAny*)
63 // Start a server for zombie to connect to.
65 TInt r = ipcServer.CreateGlobal(KAsidIpcServerName);
66 TEST_R(r, r == KErrNone);
68 for (TUint i = 0; i < 300; i++)
72 TInt r = zombie.Create(KDummyProcessName, KAsidIpcServerName);
73 TEST_R(r, r == KErrNone);
76 TEST_R(s.Int(), s.Int() == KRequestPending);
79 // Wait for the connect and ipc message from the zombie
80 ipcServer.Receive(ipcMessage);
81 TEST_R(ipcMessage.Function(), ipcMessage.Function() == EConnect);
82 ipcMessage.Complete(KErrNone);
83 ipcServer.Receive(ipcMessage);
84 TEST_R(ipcMessage.Function(), ipcMessage.Function() == EIpcData);
86 TUint8 array1[KAsidDesLen];
87 memset(array1, KAsidValue, KAsidDesLen);
88 TPtr8 buf1(array1, KAsidDesLen, KAsidDesLen);
90 TUint8 array[KAsidDesLen];
91 TPtr8 buf(array, KAsidDesLen);
92 test_Equal(KErrNone, ipcMessage.Read(0, buf));
93 r = ipcMessage.Read(0, buf);
94 TEST_R(r, r == KErrNone);
95 r = buf.Compare(buf1);
97 ipcMessage.Complete(KErrNone);
99 // Try to read from the client while it is exiting.
100 ipcServer.Receive(ipcMessage);
101 TEST_R(ipcMessage.Function(), ipcMessage.Function() == EIpcData);
104 r = ipcMessage.Read(0, buf);
105 //RDebug::Printf("%d", r);
107 // Wait for client to exit.
108 User::WaitForRequest(s);
109 TEST_R(s.Int(), s.Int() == KErrNone);
110 ipcServer.Receive(ipcMessage); // Clear out the disconnect message.
111 TEST_R(ipcMessage.Function(), ipcMessage.Function() == EDisConnect);
112 ipcMessage.Complete(KErrNone);
120 TInt TestDesThread(TAny*)
123 TInt r = asidLdd.Open();
124 TEST_R(r, r == KErrNone);
125 RMessage2 desMessage;
127 // Start a server for zombie to connect to.
128 r = desServer.CreateGlobal(KAsidDesServerName);
129 TEST_R(r, r == KErrNone);
131 for (TUint i = 0; i < 300; i++)
133 // Start the process.
135 r = zombie.Create(KDummyProcessName, KAsidDesServerName);
136 TEST_R(r, r == KErrNone);
139 TEST_R(s.Int(), s.Int() == KRequestPending);
142 // Wait for the connect and des message from the zombie
143 desServer.Receive(desMessage);
144 TEST_R(desMessage.Function(), desMessage.Function() == EConnect);
145 desMessage.Complete(KErrNone);
146 desServer.Receive(desMessage);
147 TEST_R(desMessage.Function(), desMessage.Function() == EDesData);
149 TAny* desPtr = (TAny*)desMessage.Ptr0();
150 TAny* threadPtr = (TAny*)desMessage.Ptr1();
151 // Open a handle on the client's thread to stop it being deleted.
152 r = asidLdd.OpenThread(threadPtr);
153 TEST_R(r, r == KErrNone);
155 desHdr.iDes = desPtr;
156 r = asidLdd.ReadDesHeader(threadPtr, desHdr);
157 TEST_R(r, r == KErrNone);
158 TEST_R(desHdr.iLength, desHdr.iLength == KAsidDesLen);
159 TEST_R(desHdr.iMaxLength, desHdr.iMaxLength == KAsidDesLen);
160 desMessage.Complete(KErrNone);
162 // Wait for further des message from client.
163 desServer.Receive(desMessage);
164 TEST_R(desMessage.Function(), desMessage.Function() == EDesData);
165 desPtr = (TAny*)desMessage.Ptr0();
166 TEST_R((TInt)desMessage.Ptr1(), (TInt)desMessage.Ptr1() == (TInt)threadPtr);
168 // Try to read descriptor header from the client while it is exiting.
169 TInt r = asidLdd.ReadDesHeader(threadPtr, desHdr);
172 //RDebug::Printf("%d", r);
175 TEST_R(desHdr.iLength, desHdr.iLength == KAsidDesLen);
176 TEST_R(desHdr.iMaxLength, desHdr.iMaxLength == KAsidDesLen);
179 // Wait for client to exit.
180 User::WaitForRequest(s);
181 TEST_R(s.Int(), s.Int() == KErrNone);
182 desServer.Receive(desMessage); // Clear out the disconnect message.
183 TEST_R(desMessage.Function(), desMessage.Function() == EDisConnect);
184 desMessage.Complete(KErrNone);
185 // Close handles in client process and thread.
186 r = asidLdd.CloseThread();
187 TEST_R(r, r == KErrNone);
195 GLDEF_C TInt E32Main()
198 test.Start(_L("Test zombie processes release their ASIDs"));
201 if ((UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL)&EMemModelTypeMask) < EMemModelTypeFlexible)
203 test.Printf(_L("SKIPPING TEST - Older memory models don't release ASIDs from zombie processes\n"));
210 test.Next(_L("Test ipc message copy to a zombie process"));
212 test_KErrNone(TestIpcThread(NULL));
215 test.Next(_L("Test reading descriptor header from a zombie process"));
216 test_KErrNone(TestDesThread(NULL));
219 test.Next(_L("Test ipc and des header to zombie processes concurrently"));
222 ipcThread.Create(KNullDesC, TestIpcThread, 0x2000, NULL, NULL);
223 desThread.Create(KNullDesC, TestDesThread, 0x2000, NULL, NULL);
224 TRequestStatus ipcStatus;
225 TRequestStatus desStatus;
226 ipcThread.Logon(ipcStatus);
227 desThread.Logon(desStatus);
231 // Wait for threads to complete.
232 User::WaitForRequest(ipcStatus);
233 test_KErrNone(ipcStatus.Int());
234 User::WaitForRequest(desStatus);
235 test_KErrNone(desStatus.Int());