kernel/eka/nkernsmp/arm/ncsched.cia
changeset 201 43365a9b78a3
parent 90 947f0dc9f7a8
child 221 39b39e1a406e
equal deleted inserted replaced
200:73ea206103e6 201:43365a9b78a3
   947 	asm("cmp	r3, #0 ");
   947 	asm("cmp	r3, #0 ");
   948 	asm("ble	0f ");					// thread isn't timesliced or timeslice already expired so skip
   948 	asm("ble	0f ");					// thread isn't timesliced or timeslice already expired so skip
   949 	asm("cmp	r12, #0 ");
   949 	asm("cmp	r12, #0 ");
   950 	asm("bne	0f ");					// initial (i.e. idle) thread, so skip
   950 	asm("bne	0f ");					// initial (i.e. idle) thread, so skip
   951 	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
   951 	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
   952 	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerPeriodM));
   952 	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqRI.iI.iM));
   953 	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerPeriodS));
   953 	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqRI.iI.iX));
   954 	asm("cmp	r3, #0 ");
   954 	asm("cmp	r3, #0 ");
   955 	asm("movmi	r0, #0 ");				// if timer count is negative, save zero
   955 	asm("movmi	r0, #0 ");				// if timer count is negative, save zero
   956 	asm("bmi	1f ");
   956 	asm("bmi	1f ");
   957 	asm("umull	r0, r3, r12, r3 ");		// scale up to max timer clock (R3:R0)
   957 	asm("mov	r2, r2, lsl #16 ");
       
   958 	asm("mov	r2, r2, asr #16 ");
       
   959 	asm("umull	r0, r3, r12, r3 ");		// scale up to max timer clock (R3:R0) - need to shift right by -iX
       
   960 	asm("rsb	r2, r2, #0 ");
   958 	asm("rsb	r12, r2, #32 ");
   961 	asm("rsb	r12, r2, #32 ");
   959 	asm("movs	r0, r0, lsr r2 ");		// r0 >>= iSSX.iTimerPeriodS, C = last bit shifted off (rounding)
   962 	asm("movs	r0, r0, lsr r2 ");		// r0 >>= iSSX.iTimerFreqRI.iI.iX, C = last bit shifted off (rounding)
   960 	asm("orr	r0, r0, r3, lsl r12 ");	// bottom bits from r12 into top bits of r0
   963 	asm("orr	r0, r0, r3, lsl r12 ");	// bottom bits from r3 into top bits of r0
   961 	asm("adcs	r0, r0, #0 ");			// round using last bit shifted off
   964 	asm("adcs	r0, r0, #0 ");			// round using last bit shifted off
   962 	asm("1:		");
   965 	asm("1:		");
   963 	asm("str	r0, [r1, #%a0]" : : "i" _FOFF(NThreadBase,iTime));
   966 	asm("str	r0, [r1, #%a0]" : : "i" _FOFF(NThreadBase,iTime));
   964 	asm("0:		");
   967 	asm("0:		");
   965 	__JUMP(,lr);
   968 	__JUMP(,lr);
   969 #if defined(__UTT_MACHINE_CODED__)
   972 #if defined(__UTT_MACHINE_CODED__)
   970 #if defined(__NKERN_TIMESTAMP_USE_LOCAL_TIMER__)
   973 #if defined(__NKERN_TIMESTAMP_USE_LOCAL_TIMER__)
   971 #error Use of local timer for NKern::Timestamp() no longer supported
   974 #error Use of local timer for NKern::Timestamp() no longer supported
   972 #else
   975 #else
   973 
   976 
   974 /*	Update aOld's execution time and set up the timer for aNew
   977 #error UpdateThreadTimes assembler out of date!
   975 	Update this CPU's timestamp value
       
   976 
       
   977 	if (!aOld) aOld=iInitialThread
       
   978 	if (!aNew) aNew=iInitialThread
       
   979 	newcount = aNew->iTime>0 ? Max(aNew->iTime*iSSX.iTimerFreqM/2^(32+iTimerFreqS), 1) : 2^31-1
       
   980 	cli()
       
   981 	oldcount = timer count
       
   982 	if (oldcount<=0 || aOld!=aNew)
       
   983 		{
       
   984 		timer count = newcount
       
   985 		iSSX.iLastTimerSet = newcount
       
   986 		if (aOld!=aNew)
       
   987 			{
       
   988 			TUint64 now = NKern::Timestamp();
       
   989 			elapsed = iLastTimestamp -= now;
       
   990 			iLastTimestamp = now;
       
   991 			aOld->iTotalCpuTime.i64 += elapsed;
       
   992 			if (!aOld->iActiveState)
       
   993 				aOld->iTotalActiveTime.i64 += (now - aOld->iLastActivationTime.i64);
       
   994 			++iReschedCount.i64;
       
   995 			++aNew->iRunCount.i64;
       
   996 			}
       
   997 		}
       
   998 	sti()
       
   999  */
       
  1000 __NAKED__ void TSubScheduler::UpdateThreadTimes(NThreadBase* /*aOld*/, NThreadBase* /*aNew*/)
       
  1001 	{
       
  1002 	asm("cmp	r2, #0 ");
       
  1003 	asm("ldreq	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iInitialThread));
       
  1004 	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqM));
       
  1005 	asm("cmp	r1, #0 ");
       
  1006 	asm("ldreq	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iInitialThread));
       
  1007 	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iTime));
       
  1008 	asm("stmfd	sp!, {r4-r7} ");
       
  1009 	asm("cmp	r1, r2 ");
       
  1010 	asm("beq	2f ");
       
  1011 	asm("ldr	r6, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[0]));
       
  1012 	asm("ldr	r7, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[1]));
       
  1013 	asm("adds	r6, r6, #1 ");
       
  1014 	asm("str	r6, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[0]));
       
  1015 	asm("ldr	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[0]));
       
  1016 	asm("ldr	r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[1]));
       
  1017 	asm("adcs	r7, r7, #0 ");
       
  1018 	asm("str	r7, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[1]));
       
  1019 	asm("adds	r4, r4, #1 ");
       
  1020 	asm("adcs	r6, r6, #0 ");
       
  1021 	asm("str	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[0]));
       
  1022 	asm("str	r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[1]));
       
  1023 	asm("2:		");
       
  1024 	asm("ldr	r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));
       
  1025 	asm("cmp	r3, #1 ");					// aNew->iTime > 0 ?
       
  1026 	asm("movlt	r3, #0x7fffffff ");			// if not, use 2^31-1
       
  1027 	asm("blt	3f ");
       
  1028 	asm("cmp	r1, r2 ");					// different thread?
       
  1029 	asm("beq	0f ");						// no - finish
       
  1030 	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqS));
       
  1031 	asm("umull	r4, r3, r12, r3 ");			// r3:r4 = aNew->iTime * iTimerFreqM
       
  1032 	asm("adds	r4, r4, r4 ");				// bit 31 into C
       
  1033 	asm("teq	r5, #0 ");					// check for iTimerFreqS=0 without changing C
       
  1034 	asm("movnes	r3, r3, lsr r5 ");			// if not, r3>>=iTimerFreqS, last bit shifted out into C
       
  1035 	asm("adcs	r3, r3, #0 ");				// round using last bit shifted off
       
  1036 	asm("3:		");
       
  1037 	asm("str	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLastTimerSet));
       
  1038 	asm("str	r3, [r6, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));	// set new timeslice value in timer
       
  1039 
       
  1040 	asm("ldr	r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[0]));
       
  1041 	asm("ldr	r7, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[1]));
       
  1042 	asm("stmfd	sp!, {r0-r2,lr} ");
       
  1043 	asm("bl		Timestamp__5NKern ");		// R1:R0 = current time
       
  1044 	asm("mov	r4, r0 ");
       
  1045 	asm("mov	r5, r1 ");					// R5:R4 = current time
       
  1046 	asm("ldmfd	sp!, {r0-r2,lr} ");
       
  1047 	asm("str	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[0]));
       
  1048 	asm("ldr	r3, [r1, #%a0]!" : : "i" _FOFF(NThreadBase,iTotalCpuTime.i64));
       
  1049 	asm("ldr	r12, [r1, #4] ");
       
  1050 	asm("str	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[1]));
       
  1051 	asm("stmdb	r1, {r4-r5} ");				// aOld->iLastRunTime
       
  1052 	asm("ldrb	r2, [r1, #%a0]" : : "i" (_FOFF(NSchedulable,iActiveState)-_FOFF(NThreadBase,iTotalCpuTime.i64)));
       
  1053 	asm("subs	r6, r4, r6 ");
       
  1054 	asm("sbcs	r7, r5, r7 ");				// R7:R6 = time since last reschedule
       
  1055 	asm("adds	r3, r3, r6 ");
       
  1056 	asm("adcs	r12, r12, r7 ");			// total CPU time of old thread
       
  1057 	asm("stmia	r1!, {r3,r12} ");			// store, r1=&aOld.iLastActivationTime
       
  1058 	asm("cmp	r2, #0 ");					// old thread still active?
       
  1059 	asm("bne	0f ");						// yes - done
       
  1060 	asm("ldmia	r1!, {r2,r3,r6,r7} ");		// R3:R2 = last activation time, R7:R6=total active time
       
  1061 	asm("subs	r2, r4, r2 ");
       
  1062 	asm("sbcs	r3, r5, r3 ");				// R3:R2 = time since last activation
       
  1063 	asm("adds	r6, r6, r2 ");
       
  1064 	asm("adcs	r7, r7, r3 ");				// R7:R6 = new total active time
       
  1065 	asm("stmdb	r1, {r6,r7} ");
       
  1066 
       
  1067 	asm("0:		");
       
  1068 	asm("ldmfd	sp!, {r4-r7} ");
       
  1069 	__JUMP(,lr);
       
  1070 	}
       
  1071 
   978 
  1072 #endif
   979 #endif
  1073 #endif	// __UTT_MACHINE_CODED__
   980 #endif	// __UTT_MACHINE_CODED__