kernel/eka/nkernsmp/x86/ncsched.cpp
branchRCL_3
changeset 44 3e88ff8f41d5
parent 43 c1f20ce4abcf
equal deleted inserted replaced
43:c1f20ce4abcf 44:3e88ff8f41d5
    53 
    53 
    54 extern "C" void send_resched_ipi(TInt aCpu)
    54 extern "C" void send_resched_ipi(TInt aCpu)
    55 	{
    55 	{
    56 	TSubScheduler& ss = TheSubSchedulers[aCpu];
    56 	TSubScheduler& ss = TheSubSchedulers[aCpu];
    57 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@%d",aCpu));
    57 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@%d",aCpu));
    58 	send_ipi(ss.iSSX.iAPICID);
    58 	send_ipi((TUint32)ss.i_APICID);
    59 	}
    59 	}
    60 
       
    61 #ifndef __USE_LOGICAL_DEST_MODE__
       
    62 extern "C" void __fastcall do_send_resched_ipis(TUint32 aMask)
       
    63 	{
       
    64 	TInt i=0;
       
    65 	for (; aMask; aMask>>=1, ++i)
       
    66 		if (aMask&1)
       
    67 			send_resched_ipi(i);
       
    68 	}
       
    69 #endif
       
    70 
    60 
    71 extern "C" void send_resched_ipis(TUint32 aMask)
    61 extern "C" void send_resched_ipis(TUint32 aMask)
    72 	{
    62 	{
    73 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@%02x",aMask));
    63 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@%02x",aMask));
    74 	TScheduler& s = TheScheduler;
    64 #ifdef __USE_LOGICAL_DEST_MODE__
    75 	if (aMask &~ s.iThreadAcceptCpus)
    65 	do_send_resched_ipis(aMask);
    76 		aMask = s.ReschedInactiveCpus(aMask);
    66 #else
    77 	if (aMask)
    67 	TInt i=0;
    78 		do_send_resched_ipis(aMask);
    68 	while (aMask)
       
    69 		{
       
    70 		if (aMask&1)
       
    71 			send_resched_ipi(i);
       
    72 		aMask>>=1;
       
    73 		++i;
       
    74 		}
       
    75 #endif
    79 	}
    76 	}
    80 
    77 
    81 extern "C" void send_resched_ipi_and_wait(TInt aCpu)
    78 extern "C" void send_resched_ipi_and_wait(TInt aCpu)
    82 	{
    79 	{
    83 	TSubScheduler& ss = TheSubSchedulers[aCpu];
    80 	TSubScheduler& ss = TheSubSchedulers[aCpu];
    84 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@@%d",aCpu));
    81 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@@%d",aCpu));
    85 	volatile TUint32& irqc = ss.iSSX.iIrqCount;
    82 	volatile TUint32& irqc = (volatile TUint32&)ss.i_IrqCount;
    86 	volatile TInt& irqn = ss.iSSX.iIrqNestCount;
    83 	volatile TInt& irqn = (volatile TInt&)ss.i_IrqNestCount;
    87 	TUint32 irqc0 = irqc;
    84 	TUint32 irqc0 = irqc;
    88 	mb();
    85 	mb();
    89 	send_ipi(ss.iSSX.iAPICID);
    86 	send_ipi((TUint32)ss.i_APICID);
    90 	mb();
    87 	mb();
    91 	while (!ss.iRescheduleNeededFlag || (irqn<0 && irqc==irqc0))
    88 	while (!ss.iRescheduleNeededFlag || (irqn<0 && irqc==irqc0))
    92 		{
    89 		{
    93 		__chill();
    90 		__chill();
    94 		}
    91 		}
    97 
    94 
    98 void TSubScheduler::SaveTimesliceTimer(NThreadBase* aT)
    95 void TSubScheduler::SaveTimesliceTimer(NThreadBase* aT)
    99 	{
    96 	{
   100 	if (aT->iTime>0 && !aT->i_NThread_Initial)
    97 	if (aT->iTime>0 && !aT->i_NThread_Initial)
   101 		{
    98 		{
   102 		TUint32 x = read_apic_reg(CURRCNT);
    99 		TUint32 remain32 = read_apic_reg(CURRCNT);
   103 		iSSX.iTimerFreqRI.iI.Mult(x);
   100 		TUint64 x(remain32);
       
   101 		x *= TUint32(i_TimerMultI);
       
   102 		x += 0x00800000u;
       
   103 		x >>= 24;
   104 		aT->iTime = (TInt)x;
   104 		aT->iTime = (TInt)x;
   105 		}
   105 		}
   106 	write_apic_reg(INITCNT, 0);
   106 	write_apic_reg(INITCNT, 0);
   107 	}
   107 	}
   108 
   108 
   123 		aOld = iInitialThread;
   123 		aOld = iInitialThread;
   124 	if (!aNew)
   124 	if (!aNew)
   125 		aNew = iInitialThread;
   125 		aNew = iInitialThread;
   126 	if (aNew->iTime>0)
   126 	if (aNew->iTime>0)
   127 		{
   127 		{
   128 		TUint32 x = (TUint32)aNew->iTime;
   128 		TUint32 remain32 = (TUint32)aNew->iTime;
   129 		iSSX.iTimerFreqRI.iR.Mult(x);
   129 		TUint64 x(remain32);
   130 		write_apic_reg(INITCNT, x);
   130 		x *= TUint32(i_TimerMultF);
       
   131 		x += 0x80000000u;
       
   132 		x >>= 32;
       
   133 		write_apic_reg(LVTTMR, TIMESLICE_VECTOR);
       
   134 		write_apic_reg(INITCNT, (TUint32)x);
   131 		}
   135 		}
   132 	if (aNew!=aOld)
   136 	if (aNew!=aOld)
   133 		{
   137 		{
   134 		TUint64 now = NKern::Timestamp();
   138 		TUint64 now = NKern::Timestamp();
   135 		TUint64 delta = now - iLastTimestamp.i64;
   139 		aOld->iTotalCpuTime64 += (now - iLastTimestamp64);
   136 		iLastTimestamp.i64 = now;
   140 		iLastTimestamp64 = now;
   137 		aOld->iLastRunTime.i64 = now;
   141 		++iReschedCount64;
   138 		aOld->iTotalCpuTime.i64 += delta;
   142 		++aNew->iRunCount64;
   139 		++iReschedCount.i64;
       
   140 		++aNew->iRunCount.i64;
       
   141 		if (!aOld->iActiveState)
       
   142 			aOld->iTotalActiveTime.i64 += (now - aOld->iLastActivationTime.i64);
       
   143 		NSchedulable* parent = aOld->iParent;
       
   144 		if (parent != aOld)
       
   145 			{
       
   146 			parent->iLastRunTime.i64 = now;
       
   147 			if (!parent->iActiveState)
       
   148 				parent->iTotalActiveTime.i64 += (now - parent->iLastActivationTime.i64);
       
   149 			if (parent != aNew->iParent)
       
   150 				parent->iTotalCpuTime.i64 += (now - parent->iLastStartTime.i64);
       
   151 			}
       
   152 		NSchedulable* np = aNew->iParent;
       
   153 		if (np!=aNew && np!=parent)
       
   154 			np->iLastStartTime.i64 = now;
       
   155 		}
   143 		}
   156 	}
   144 	}
   157 
   145 
   158 
   146