--- a/kernel/eka/nkernsmp/arm/ncsched.cia Wed Jun 23 12:52:28 2010 +0100
+++ b/kernel/eka/nkernsmp/arm/ncsched.cia Wed Jun 23 12:58:21 2010 +0100
@@ -949,15 +949,18 @@
asm("cmp r12, #0 ");
asm("bne 0f "); // initial (i.e. idle) thread, so skip
asm("ldr r3, [r2, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
- asm("ldr r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerPeriodM));
- asm("ldr r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerPeriodS));
+ asm("ldr r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqRI.iI.iM));
+ asm("ldr r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqRI.iI.iX));
asm("cmp r3, #0 ");
asm("movmi r0, #0 "); // if timer count is negative, save zero
asm("bmi 1f ");
- asm("umull r0, r3, r12, r3 "); // scale up to max timer clock (R3:R0)
+ asm("mov r2, r2, lsl #16 ");
+ asm("mov r2, r2, asr #16 ");
+ asm("umull r0, r3, r12, r3 "); // scale up to max timer clock (R3:R0) - need to shift right by -iX
+ asm("rsb r2, r2, #0 ");
asm("rsb r12, r2, #32 ");
- asm("movs r0, r0, lsr r2 "); // r0 >>= iSSX.iTimerPeriodS, C = last bit shifted off (rounding)
- asm("orr r0, r0, r3, lsl r12 "); // bottom bits from r12 into top bits of r0
+ asm("movs r0, r0, lsr r2 "); // r0 >>= iSSX.iTimerFreqRI.iI.iX, C = last bit shifted off (rounding)
+ asm("orr r0, r0, r3, lsl r12 "); // bottom bits from r3 into top bits of r0
asm("adcs r0, r0, #0 "); // round using last bit shifted off
asm("1: ");
asm("str r0, [r1, #%a0]" : : "i" _FOFF(NThreadBase,iTime));
@@ -971,103 +974,7 @@
#error Use of local timer for NKern::Timestamp() no longer supported
#else
-/* Update aOld's execution time and set up the timer for aNew
- Update this CPU's timestamp value
-
- if (!aOld) aOld=iInitialThread
- if (!aNew) aNew=iInitialThread
- newcount = aNew->iTime>0 ? Max(aNew->iTime*iSSX.iTimerFreqM/2^(32+iTimerFreqS), 1) : 2^31-1
- cli()
- oldcount = timer count
- if (oldcount<=0 || aOld!=aNew)
- {
- timer count = newcount
- iSSX.iLastTimerSet = newcount
- if (aOld!=aNew)
- {
- TUint64 now = NKern::Timestamp();
- elapsed = iLastTimestamp -= now;
- iLastTimestamp = now;
- aOld->iTotalCpuTime.i64 += elapsed;
- if (!aOld->iActiveState)
- aOld->iTotalActiveTime.i64 += (now - aOld->iLastActivationTime.i64);
- ++iReschedCount.i64;
- ++aNew->iRunCount.i64;
- }
- }
- sti()
- */
-__NAKED__ void TSubScheduler::UpdateThreadTimes(NThreadBase* /*aOld*/, NThreadBase* /*aNew*/)
- {
- asm("cmp r2, #0 ");
- asm("ldreq r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iInitialThread));
- asm("ldr r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqM));
- asm("cmp r1, #0 ");
- asm("ldreq r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iInitialThread));
- asm("ldr r3, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iTime));
- asm("stmfd sp!, {r4-r7} ");
- asm("cmp r1, r2 ");
- asm("beq 2f ");
- asm("ldr r6, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[0]));
- asm("ldr r7, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[1]));
- asm("adds r6, r6, #1 ");
- asm("str r6, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[0]));
- asm("ldr r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[0]));
- asm("ldr r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[1]));
- asm("adcs r7, r7, #0 ");
- asm("str r7, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[1]));
- asm("adds r4, r4, #1 ");
- asm("adcs r6, r6, #0 ");
- asm("str r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[0]));
- asm("str r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[1]));
- asm("2: ");
- asm("ldr r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));
- asm("cmp r3, #1 "); // aNew->iTime > 0 ?
- asm("movlt r3, #0x7fffffff "); // if not, use 2^31-1
- asm("blt 3f ");
- asm("cmp r1, r2 "); // different thread?
- asm("beq 0f "); // no - finish
- asm("ldr r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqS));
- asm("umull r4, r3, r12, r3 "); // r3:r4 = aNew->iTime * iTimerFreqM
- asm("adds r4, r4, r4 "); // bit 31 into C
- asm("teq r5, #0 "); // check for iTimerFreqS=0 without changing C
- asm("movnes r3, r3, lsr r5 "); // if not, r3>>=iTimerFreqS, last bit shifted out into C
- asm("adcs r3, r3, #0 "); // round using last bit shifted off
- asm("3: ");
- asm("str r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLastTimerSet));
- asm("str r3, [r6, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount)); // set new timeslice value in timer
-
- asm("ldr r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[0]));
- asm("ldr r7, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[1]));
- asm("stmfd sp!, {r0-r2,lr} ");
- asm("bl Timestamp__5NKern "); // R1:R0 = current time
- asm("mov r4, r0 ");
- asm("mov r5, r1 "); // R5:R4 = current time
- asm("ldmfd sp!, {r0-r2,lr} ");
- asm("str r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[0]));
- asm("ldr r3, [r1, #%a0]!" : : "i" _FOFF(NThreadBase,iTotalCpuTime.i64));
- asm("ldr r12, [r1, #4] ");
- asm("str r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[1]));
- asm("stmdb r1, {r4-r5} "); // aOld->iLastRunTime
- asm("ldrb r2, [r1, #%a0]" : : "i" (_FOFF(NSchedulable,iActiveState)-_FOFF(NThreadBase,iTotalCpuTime.i64)));
- asm("subs r6, r4, r6 ");
- asm("sbcs r7, r5, r7 "); // R7:R6 = time since last reschedule
- asm("adds r3, r3, r6 ");
- asm("adcs r12, r12, r7 "); // total CPU time of old thread
- asm("stmia r1!, {r3,r12} "); // store, r1=&aOld.iLastActivationTime
- asm("cmp r2, #0 "); // old thread still active?
- asm("bne 0f "); // yes - done
- asm("ldmia r1!, {r2,r3,r6,r7} "); // R3:R2 = last activation time, R7:R6=total active time
- asm("subs r2, r4, r2 ");
- asm("sbcs r3, r5, r3 "); // R3:R2 = time since last activation
- asm("adds r6, r6, r2 ");
- asm("adcs r7, r7, r3 "); // R7:R6 = new total active time
- asm("stmdb r1, {r6,r7} ");
-
- asm("0: ");
- asm("ldmfd sp!, {r4-r7} ");
- __JUMP(,lr);
- }
+#error UpdateThreadTimes assembler out of date!
#endif
#endif // __UTT_MACHINE_CODED__