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 |