GLDEF_C TInt E32Main() { test.Title(); test.Start(_L("Waiting...")); RUndertaker u; TInt r=u.Create(); test(r==KErrNone); //to avoid RVCT4 warning of unreachable statement. volatile TInt forever = 0; while(forever) { TInt h; TRequestStatus s; r=u.Logon(s,h); test(r==KErrNone); User::WaitForRequest(s); RThread t; t.SetHandle(h); TBuf8<128> b; t.Context(b); TInt *pR=(TInt*)b.Ptr(); TFullName tFullName = t.FullName(); TExitCategoryName tExitCategory = t.ExitCategory(); test.Printf(_L("Thread %S Exit %d %S %d\n"),&tFullName,t.ExitType(),&tExitCategory,t.ExitReason()); test.Printf(_L("r0 =%08x r1 =%08x r2 =%08x r3 =%08x\n"),pR[0],pR[1],pR[2],pR[3]); test.Printf(_L("r4 =%08x r5 =%08x r6 =%08x r7 =%08x\n"),pR[4],pR[5],pR[6],pR[7]); test.Printf(_L("r8 =%08x r9 =%08x r10=%08x r11=%08x\n"),pR[8],pR[9],pR[10],pR[11]); test.Printf(_L("r12=%08x r13=%08x r14=%08x r15=%08x\n"),pR[12],pR[13],pR[14],pR[15]); test.Printf(_L("cps=%08x dac=%08x\n"),pR[16],pR[17]); t.Close(); } return 0; }
void SDL_SYS_WaitThread(SDL_Thread *thread) { RUndertaker taker; taker.Create(); TRequestStatus status; taker.Logon(status, thread->handle); User::WaitForRequest(status); taker.Close(); }
TInt ThreadFunc(TAny* anArgument) { CSharedData* mySharedData = reinterpret_cast<CSharedData*> (anArgument); RUndertaker u; u.Create(); TRequestStatus status; TInt deadThread; TBool clientWaiting = ETrue; FOREVER { status = KRequestPending; u.Logon(status,deadThread); // wait for the next thread to die. if (clientWaiting) { // rendezvous with the client so that they know we're ready. // This guarantees that we will catch at least the first panic to // occur (as long as we aren't closed before kernel tells us. RThread::Rendezvous(KErrNone); clientWaiting = EFalse; } User::WaitForRequest(status); // until we get back around to the top we are missing notifications now. // being high priority helps us, but still... // deal with this QUICKLY // get handle to the dead thread (this has already been marked for us in // the kernel) RThread t; t.SetHandle(deadThread); if (t.ExitType() == EExitPanic) { // the other ways threads can die are uninteresting TTime now; now.UniversalTime(); TThreadPanicDetails* tpd = new TThreadPanicDetails (t.Name(), t.ExitReason(),t.ExitCategory(),now); mySharedData->iPanicDetails.AppendL(tpd); } t.Close(); } }
static TInt CatalogsUndertaker() { DLTRACEIN(("")); TFullName catalogsThreadName; TInt err = User::GetDesParameter( 15, catalogsThreadName ); if( err != KErrNone ) { DLERROR(( "Failed to read parameter slot 15, error %d", err )); catalogsThreadName = KNullDesC(); } else { DLINFO(( _L("Read catalogs thread name: %S"), &catalogsThreadName )); } RUndertaker undertaker; TRequestStatus status; TInt deadThreadHandleNumber; undertaker.Create(); for( ;; ) { undertaker.Logon( status, deadThreadHandleNumber ); User::WaitForRequest( status ); RThread deadThread; deadThread.SetHandle( deadThreadHandleNumber ); const TDesC* type; switch( deadThread.ExitType() ) { case EExitKill: type = &KExitTypeKill; break; case EExitTerminate: type = &KExitTypeTerminate; break; case EExitPanic: type = &KExitTypePanic; break; default: type = &KExitTypeUnknown; DLERROR(( "Exit type: %d", (TInt)deadThread.ExitType() )); break; } DLWARNING(( _L("THREAD %S DEATH observed! %S %S %d"), &deadThread.FullName(), type, &deadThread.ExitCategory(), deadThread.ExitReason() )); type = type; // to suppress compiler warning if( catalogsThreadName == deadThread.FullName() ) { DLERROR(( "Catalogs server thread killed, undertaker exits" )); deadThread.Close(); break; } deadThread.Close(); } undertaker.Close(); DLTRACEOUT(("KErrNone")); return KErrNone; }
//! @SYMTestCaseID t_cputime_1 //! @SYMTestType CT //! @SYMTestCaseDesc Thread CPU time tests //! @SYMREQ CR RFID-66JJKX //! @SYMTestActions Tests cpu time when a thread is put through the various states //! @SYMTestExpectedResults Reported cpu time increses only when the thread is running //! @SYMTestPriority High //! @SYMTestStatus Defined void TestThreadCpuTime() { test.Start(_L("CPU thread time unit tests")); TThreadParam threadParam; FailIfError((threadParam.iSem).CreateLocal(0)); threadParam.iCpu = 0; // Later tests will exercise other CPUs RThread thread; RUndertaker u; TInt h; TRequestStatus s; FailIfError(thread.Create(_L("Thread"), ThreadFunction, 1024, NULL, &threadParam)); thread.SetPriority(EPriorityLess); FailIfError(u.Create()); FailIfError(u.Logon(s,h)); test(s==KRequestPending); TTimeIntervalMicroSeconds time, time2; TInt64 us; // Test cpu time is initially zero FailIfError(thread.GetCpuTime(time)); test(time == 0); // Test cpu time is not increased while thread is waiting on semaphore thread.Resume(); User::After(KShortWait); FailIfError(thread.GetCpuTime(time2)); us = time2.Int64(); test.Printf(_L("Time %dus\n"), us); test(us < KTolerance); // wait should happen in less than 1ms // Test cpu time increases when thread allowed to run // We want to allow 2% tolerance for the thread's CPU time, as there could be // something else running on the system during that time which would result lower CPU time than the // actual KShortPeriod or KLongPeriod wait time. // Also User::After(t) might return within the range of <t, t + 1000000/64 + 2*NanoKarnelTickPeriod>. // Given all that - we expect that the the cpu time should be within the range of: // <t - 0.02*t, t + 15625 + 2*NanoKernelTickPeriod> // or <0.98*t, t + 15625 + 2*NanoKernelTickPeriod> TInt user_after_tolerance = 0; HAL::Get(HAL::ENanoTickPeriod, user_after_tolerance); user_after_tolerance += user_after_tolerance + 15625; (threadParam.iSem).Signal(); User::After(KShortWait); FailIfError(thread.GetCpuTime(time)); us = time.Int64() - time2.Int64(); test.Printf(_L("Time %dus\n"), us); test(100*us >= 98*KShortWait); // left limit test(us - KShortWait <= user_after_tolerance); // right limit FailIfError(thread.GetCpuTime(time)); User::After(KLongWait); FailIfError(thread.GetCpuTime(time2)); us = time2.Int64() - time.Int64(); test.Printf(_L("Time %dus\n"), us); test(100*us >= 98*KLongWait); // left limit test(us - KLongWait <= user_after_tolerance); // right limit // Test not increased while suspended thread.Suspend(); FailIfError(thread.GetCpuTime(time)); User::After(KShortWait); FailIfError(thread.GetCpuTime(time2)); test(time == time2); thread.Resume(); // Test not increased while dead thread.Kill(KErrNone); User::WaitForRequest(s); // wait on undertaker since that completes in supervisor thread FailIfError(thread.GetCpuTime(time)); User::After(KShortWait); FailIfError(thread.GetCpuTime(time2)); test(time == time2); RThread t; t.SetHandle(h); test(t.Id()==thread.Id()); t.Close(); u.Close(); thread.Close(); (threadParam.iSem).Close(); test.End(); }