diff -r 73ea206103e6 -r 43365a9b78a3 kernel/eka/nkernsmp/arm/ncsched.cia --- a/kernel/eka/nkernsmp/arm/ncsched.cia Wed Jun 23 19:44:53 2010 +0300 +++ b/kernel/eka/nkernsmp/arm/ncsched.cia Tue Jul 06 15:50:07 2010 +0300 @@ -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__