kernel/eka/kernel/sthread.cpp
changeset 279 957c583b417b
parent 177 a232af6b0b1f
equal deleted inserted replaced
275:2b433474f2ba 279:957c583b417b
   138 	Kern::SafeClose(iExtTempObj,NULL);
   138 	Kern::SafeClose(iExtTempObj,NULL);
   139 	if (iNThread.iExtraContextSize > 0)
   139 	if (iNThread.iExtraContextSize > 0)
   140 		Kern::Free(iNThread.iExtraContext);
   140 		Kern::Free(iNThread.iExtraContext);
   141 	}
   141 	}
   142 
   142 
       
   143 #if defined(__EPOC32__) && defined(KTHREAD)
       
   144 void CheckSupervisorStackUsage(DThread* aT)
       
   145 	{
       
   146 	const TUint32* p = (const TUint32*)aT->iSupervisorStack;
       
   147 	TUint32 used = 0;
       
   148 	TUint32 free = 0;
       
   149 	if (p)
       
   150 		{
       
   151 		const TUint32* pE = p + (aT->iSupervisorStackSize / sizeof(TUint32));
       
   152 		while(p<pE && *p==0xeeeeeeeeu)
       
   153 			++p;
       
   154 		used = (pE - p) * sizeof(TUint32);
       
   155 		free = TUint32(aT->iSupervisorStackSize) - used;
       
   156 		}
       
   157 	Kern::Printf("Thread %O used %d bytes of kernel stack (%d bytes free)", aT, used, free);
       
   158 	}
       
   159 #endif
       
   160 
   143 // Enter and return with system unlocked.
   161 // Enter and return with system unlocked.
   144 void DThread::Release()
   162 void DThread::Release()
   145 	{
   163 	{
   146 	__KTRACE_OPT(KTHREAD,Kern::Printf("Thread %O Release()",this));
   164 	__KTRACE_OPT(KTHREAD,Kern::Printf("Thread %O Release()",this));
   147 	if (iWaitListReserved)
   165 	if (iWaitListReserved)
   183 	// cancel the timer
   201 	// cancel the timer
   184 	__KTRACE_OPT(KTHREAD,Kern::Printf("Cancelling timer"));
   202 	__KTRACE_OPT(KTHREAD,Kern::Printf("Cancelling timer"));
   185 	iTimer.Cancel(NULL);
   203 	iTimer.Cancel(NULL);
   186 
   204 
   187 	__KTRACE_OPT(KTHREAD,Kern::Printf("Freeing supervisor-mode stack"));
   205 	__KTRACE_OPT(KTHREAD,Kern::Printf("Freeing supervisor-mode stack"));
       
   206 #if defined(__EPOC32__) && defined(KTHREAD)
       
   207 	__KTRACE_OPT(KTHREAD,CheckSupervisorStackUsage(this));
       
   208 #endif
   188 	FreeSupervisorStack();
   209 	FreeSupervisorStack();
   189 #ifdef BTRACE_THREAD_IDENTIFICATION
   210 #ifdef BTRACE_THREAD_IDENTIFICATION
   190 	BTrace12(BTrace::EThreadIdentification,BTrace::EThreadDestroy,&iNThread,iOwningProcess,iId);
   211 	BTrace12(BTrace::EThreadIdentification,BTrace::EThreadDestroy,&iNThread,iOwningProcess,iId);
   191 #endif
   212 #endif
   192 	__DEBUG_EVENT(EEventRemoveThread, this);
   213 	__DEBUG_EVENT(EEventRemoveThread, this);
   663 	TUint64 sec = aTicks / e6;
   684 	TUint64 sec = aTicks / e6;
   664 	return (sec<<32)|us;
   685 	return (sec<<32)|us;
   665 	}
   686 	}
   666 #endif
   687 #endif
   667 
   688 
       
   689 #if defined(__SMP__) && defined(KTIMING)
       
   690 void TraceStatsOnThreadExit(DThread* aT)
       
   691 	{
       
   692 	TUint64 rc = aT->iNThread.iRunCount.i64;
       
   693 	NSchedulable::SCpuStats stats;
       
   694 	NKern::Lock();
       
   695 	aT->iNThread.GetCpuStats(NSchedulable::E_RunTime|NSchedulable::E_ActiveTime, stats);
       
   696 	NKern::Unlock();
       
   697 	TUint64 cputime = stats.iRunTime;
       
   698 	TUint64 acttime = stats.iActiveTime;
       
   699 	TUint32 f = NKern::CpuTimeMeasFreq();
       
   700 	TUint64 avgcpu = rc ? cputime / rc : 0;
       
   701 	TUint64 ratio = (acttime*100)/cputime;
       
   702 	TUint64 cpud = tix2us(cputime, f);
       
   703 	TUint64 actd = tix2us(acttime, f);
       
   704 	TUint64 avgd = tix2us(avgcpu, f);
       
   705 	Kern::Printf("Thread %O RC=%u CPU=%u.%06us ACT=%u.%06us AVG=%u.%06us RATIO=%d%%",
       
   706 					aT, TUint32(rc),
       
   707 					I64HIGH(cpud), I64LOW(cpud),
       
   708 					I64HIGH(actd), I64LOW(actd),
       
   709 					I64HIGH(avgd), I64LOW(avgd),
       
   710 					TUint32(ratio));
       
   711 	}
       
   712 #endif
       
   713 
   668 void DThread::Exit()
   714 void DThread::Exit()
   669 //
   715 //
   670 // This function runs in the context of the exiting thread
   716 // This function runs in the context of the exiting thread
   671 // Enter and leave with system unlocked
   717 // Enter and leave with system unlocked
   672 //
   718 //
   673 	{
   719 	{
   674 #if defined(__SMP__) && defined(KTIMING)
   720 #if defined(__SMP__) && defined(KTIMING)
   675 	if (KDebugNum(KTIMING))
   721 	if (KDebugNum(KTIMING))
   676 		{
   722 		TraceStatsOnThreadExit(this);
   677 		TUint64 rc = iNThread.iRunCount.i64;
       
   678 		NSchedulable::SCpuStats stats;
       
   679 		NKern::Lock();
       
   680 		iNThread.GetCpuStats(NSchedulable::E_RunTime|NSchedulable::E_ActiveTime, stats);
       
   681 		NKern::Unlock();
       
   682 		TUint64 cputime = stats.iRunTime;
       
   683 		TUint64 acttime = stats.iActiveTime;
       
   684 		TUint32 f = NKern::CpuTimeMeasFreq();
       
   685 		TUint64 avgcpu = rc ? cputime / rc : 0;
       
   686 		TUint64 ratio = (acttime*100)/cputime;
       
   687 		TUint64 cpud = tix2us(cputime, f);
       
   688 		TUint64 actd = tix2us(acttime, f);
       
   689 		TUint64 avgd = tix2us(avgcpu, f);
       
   690 		Kern::Printf("Thread %O RC=%u CPU=%u.%06us ACT=%u.%06us AVG=%u.%06us RATIO=%d%%",
       
   691 						this, TUint32(rc),
       
   692 						I64HIGH(cpud), I64LOW(cpud),
       
   693 						I64HIGH(actd), I64LOW(actd),
       
   694 						I64HIGH(avgd), I64LOW(avgd),
       
   695 						TUint32(ratio));
       
   696 		}
       
   697 #endif
   723 #endif
   698 #ifdef KPANIC
   724 #ifdef KPANIC
   699 	if (iExitType==EExitPanic)
   725 	if (iExitType==EExitPanic)
   700 		{
   726 		{
   701 		__KTRACE_OPT2(KPANIC,KSCHED,Kern::Printf("Thread %O Panic %S %d",this,&iExitCategory,iExitReason));
   727 		__KTRACE_OPT2(KPANIC,KSCHED,Kern::Printf("Thread %O Panic %S %d",this,&iExitCategory,iExitReason));