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