1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/bench/t_ctxsw.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,202 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\bench\t_ctxsw.cpp
1.18 +// Overview:
1.19 +// Test and benchmark inter-thread context switch.
1.20 +// API Information:
1.21 +// RThread, RSemaphore, TRequestStatus.
1.22 +// Details:
1.23 +// - Creates a thread with a handle to a Semaphore, check for successful
1.24 +// creation and assign priority EPriorityLess.
1.25 +// - Creates another thread with the handle to the thread already created,
1.26 +// check for successful creation and assign priority EPriorityMuchLess.
1.27 +// - Makes the two threads eligible for execution.
1.28 +// - First thread counts the number of semaphore requests.
1.29 +// - Second thread counts the number of times the thread is signalled on
1.30 +// completion of request.
1.31 +// - Terminate the threads, print the count per second.
1.32 +// Platforms/Drives/Compatibility:
1.33 +// All.
1.34 +// Assumptions/Requirement/Pre-requisites:
1.35 +// Failures and causes:
1.36 +// Base Port information:
1.37 +//
1.38 +//
1.39 +
1.40 +#define __E32TEST_EXTENSION__
1.41 +#include <e32test.h>
1.42 +
1.43 +RTest test(_L("T_CTXSW"));
1.44 +
1.45 +volatile TInt Count1;
1.46 +volatile TInt Count2;
1.47 +
1.48 +TInt Thread1(TAny* aSemaphore)
1.49 + {
1.50 + RSemaphore s;
1.51 + s.SetHandle((TInt)aSemaphore);
1.52 + User::WaitForAnyRequest();
1.53 + s.Signal();
1.54 + FOREVER
1.55 + {
1.56 + User::WaitForAnyRequest();
1.57 + Count1++;
1.58 + }
1.59 + }
1.60 +
1.61 +TInt Thread2(TAny* aThread)
1.62 + {
1.63 + TRequestStatus s;
1.64 + RThread t;
1.65 + t.SetHandle((TInt)aThread);
1.66 + FOREVER
1.67 + {
1.68 + Count2++;
1.69 + TRequestStatus* ps=&s;
1.70 + t.RequestComplete(ps,0);
1.71 + }
1.72 + }
1.73 +
1.74 +const TInt KHeapSize=4096;
1.75 +void Test1()
1.76 + {
1.77 + test.Start(_L("Test 1"));
1.78 +
1.79 + RSemaphore sem;
1.80 + TInt r = sem.CreateLocal(0);
1.81 + test_KErrNone(r);
1.82 + RThread t1,t2;
1.83 + RThread* pt1, *pt2;
1.84 +
1.85 + pt1 = NULL;
1.86 + pt2 = NULL;
1.87 +
1.88 + Count1=Count2=0;
1.89 + r=t1.Create(_L("Thread1"),Thread1,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)sem.Handle());
1.90 + if (!pt1)
1.91 + pt1=&t1;
1.92 + else
1.93 + test(pt1==&t1);
1.94 +
1.95 + test_KErrNone(r);
1.96 + t1.SetPriority(EPriorityLess);
1.97 + r=t2.Create(_L("Thread2"),Thread2,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)t1.Handle());
1.98 + if (!pt2)
1.99 + pt2=&t2;
1.100 + else
1.101 + test(pt2==&t2);
1.102 + test_KErrNone(r);
1.103 + t2.SetPriority(EPriorityMuchLess);
1.104 +
1.105 + TRequestStatus s1,s2;
1.106 + t1.Logon(s1);
1.107 + t2.Logon(s2);
1.108 + t1.Resume();
1.109 + t2.Resume();
1.110 + sem.Wait();
1.111 + Count1=Count2=0;
1.112 + User::After(16000000);
1.113 + t2.Kill(0);
1.114 + User::WaitForRequest(s2);
1.115 + t1.Kill(0);
1.116 + User::WaitForRequest(s1);
1.117 +
1.118 + t2.Close();
1.119 + t1.Close();
1.120 + test.Printf(_L("Ran %d times in one second.\n"),(Count1+Count2)/16); // get the value
1.121 + sem.Close();
1.122 +
1.123 + test.End();
1.124 + }
1.125 +
1.126 +struct SThread3Info
1.127 + {
1.128 + TRequestStatus iStatus;
1.129 + TRequestStatus iLogonStatus;
1.130 + RThread iThread;
1.131 + volatile TUint32 iCount;
1.132 + SThread3Info* iOther;
1.133 + TUint32 iPadding[9];
1.134 + };
1.135 +
1.136 +void Thread3(TAny* aInfo)
1.137 + {
1.138 + SThread3Info& me = *(SThread3Info*)aInfo;
1.139 + SThread3Info& you = *me.iOther;
1.140 + FOREVER
1.141 + {
1.142 + TRequestStatus* ps = &you.iStatus;
1.143 + you.iThread.RequestComplete(ps, 0);
1.144 + User::WaitForAnyRequest();
1.145 + ++me.iCount;
1.146 + Count2++;
1.147 + }
1.148 + }
1.149 +
1.150 +void Test2()
1.151 + {
1.152 + test.Start(_L("Test 2"));
1.153 +
1.154 + SThread3Info info[2];
1.155 + TInt r;
1.156 + TInt i;
1.157 + for (i=0; i<2; ++i)
1.158 + {
1.159 + info[i].iCount = 0;
1.160 + info[i].iOther = &info[1-i];
1.161 + r = info[i].iThread.Create(KNullDesC, (TThreadFunction)&Thread3, 0x1000, 0, &info[i]);
1.162 + test_KErrNone(r);
1.163 + info[i].iThread.Logon(info[i].iLogonStatus);
1.164 + test_Equal(KRequestPending, info[i].iLogonStatus.Int());
1.165 + }
1.166 + info[0].iThread.SetPriority(EPriorityMuchLess);
1.167 + info[1].iThread.SetPriority(EPriorityLess);
1.168 + info[0].iThread.Resume();
1.169 + info[1].iThread.Resume();
1.170 + User::AfterHighRes(100000);
1.171 + TUint32 ic0 = info[0].iCount;
1.172 + TUint32 ic1 = info[1].iCount;
1.173 + User::AfterHighRes(10000000);
1.174 + info[0].iThread.Kill(0);
1.175 + info[1].iThread.Kill(0);
1.176 + User::WaitForRequest(info[0].iLogonStatus);
1.177 + User::WaitForRequest(info[1].iLogonStatus);
1.178 + test_Equal(EExitKill, info[0].iThread.ExitType());
1.179 + test_Equal(0, info[0].iThread.ExitReason());
1.180 + test_Equal(EExitKill, info[1].iThread.ExitType());
1.181 + test_Equal(0, info[1].iThread.ExitReason());
1.182 +
1.183 + TUint32 fc0 = info[0].iCount;
1.184 + TUint32 fc1 = info[1].iCount;
1.185 + test.Printf(_L("T0: Initial %10u Final %10u Diff %10u PerSec %10u\n"), ic0, fc0, (fc0-ic0), (fc0-ic0)/10);
1.186 + test.Printf(_L("T1: Initial %10u Final %10u Diff %10u PerSec %10u\n"), ic1, fc1, (fc1-ic1), (fc1-ic1)/10);
1.187 +
1.188 + CLOSE_AND_WAIT(info[0].iThread);
1.189 + CLOSE_AND_WAIT(info[1].iThread);
1.190 +
1.191 + test.End();
1.192 + }
1.193 +
1.194 +TInt E32Main()
1.195 + {
1.196 +
1.197 + test.Title();
1.198 + test.Start(_L("Timing inter-thread context switches..."));
1.199 +
1.200 + Test1();
1.201 + Test2();
1.202 +
1.203 + test.End();
1.204 + return 0;
1.205 + }