Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
5.4 KiB

  1. TITLE "Compute Timer Table Index"
  2. ;++
  3. ;
  4. ; Copyright (c) 1993 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; timindex.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements the code necessary to compute the timer table
  13. ; index for a timer.
  14. ;
  15. ; Author:
  16. ;
  17. ; David N. Cutler (davec) 19-May-1993
  18. ;
  19. ; Environment:
  20. ;
  21. ; Any mode.
  22. ;
  23. ; Revision History:
  24. ;
  25. ; Neill Clift (NeillC) 6-Jan-2001
  26. ; Use modulus reduction to reduce the number of multiplies needed.
  27. ;
  28. ;--
  29. .386p
  30. .xlist
  31. include ks386.inc
  32. include callconv.inc ; calling convention macros
  33. .list
  34. extrn _KiSlotZeroTime:dword
  35. extrn _KiMaximumIncrementReciprocal:dword
  36. extrn _KiLog2MaximumIncrement:dword
  37. extrn _KiUpperModMul:dword
  38. extrn _KeTimerReductionModulus:dword
  39. _TEXT$00 SEGMENT DWORD PUBLIC 'CODE'
  40. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  41. page
  42. subttl "Compute Timer Table Index"
  43. ;++
  44. ;
  45. ; ULONG
  46. ; KiComputeTimerTableIndex (
  47. ; IN LARGE_INTEGER Interval,
  48. ; IN LARGE_INTEGER CurrentTime,
  49. ; IN PKTIMER Timer
  50. ; )
  51. ;
  52. ; Routine Description:
  53. ;
  54. ; This function computes the timer table index for the specified timer
  55. ; object and stores the due time in the timer object.
  56. ;
  57. ; N.B. The interval parameter is guaranteed to be negative since it is
  58. ; expressed as relative time.
  59. ;
  60. ; The formula for due time calculation is:
  61. ;
  62. ; Due Time = Current Time - Interval
  63. ;
  64. ; The formula for the index calculation is:
  65. ;
  66. ; Index = (Due Time / Maximum time) & (Table Size - 1)
  67. ;
  68. ; The time increment division is performed using reciprocal multiplication.
  69. ;
  70. ; Arguments:
  71. ;
  72. ; Interval - Supplies the relative time at which the timer is to
  73. ; expire.
  74. ;
  75. ; CurrentCount - Supplies the current system tick count.
  76. ;
  77. ; Timer - Supplies a pointer to a dispatch object of type timer.
  78. ;
  79. ; Return Value:
  80. ;
  81. ; The time table index is returned as the function value and the due
  82. ; time is stored in the timer object.
  83. ;
  84. ;--
  85. Interval equ [esp+4+4]
  86. CurrentTime equ [esp+4+12]
  87. Timer equ [esp+4+20]
  88. cPublicProc _KiComputeTimerTableIndex ,5
  89. push ebx
  90. mov eax,Timer ; get address of timer object
  91. mov ebx,CurrentTime ; get low current time
  92. mov ecx,CurrentTime + 4 ; get high current time
  93. sub ebx,Interval ; subtract low parts
  94. sbb ecx,Interval + 4 ; subtract high parts and borrow
  95. mov [eax].TiDueTime.LiLowPart,ebx ; set low part of due time
  96. mov [eax].TiDueTime.LiHighPart,ecx ; set high part of due time
  97. ;
  98. ; Subtract slot zero time to see if we can use a quicker route
  99. ;
  100. sub ebx, [_KiSlotZeroTime]
  101. sbb ecx, [_KiSlotZeroTime+4]
  102. jne slow
  103. underflow_return:
  104. ;
  105. ; The upper 32 bits of the time are zero. Multiply by the 32 bit inverse
  106. ; to calculate the quotient.
  107. ;
  108. upper_zero:
  109. mov eax, [_KiMaximumIncrementReciprocal]
  110. mov ecx, [_KiLog2MaximumIncrement]
  111. mul ebx
  112. add edx, ebx
  113. rcr edx, cl
  114. if TIMER_TABLE_SIZE EQ 256
  115. movzx eax, dl
  116. else
  117. and edx, (TIMER_TABLE_SIZE-1); reduce to size of table
  118. mov eax, edx
  119. endif
  120. pop ebx
  121. stdRET _KiComputeTimerTableIndex
  122. slow: jc underflow ; Our slot zero sub underflowed
  123. test ebx, 0ff0000h
  124. je recalc_slotzero
  125. slow_resume:
  126. ;
  127. ; Try to reduce the time by multiplying the upper dword by a modulus reduction factor.
  128. ; _KiUpperModMul is (2^64) % (_KeMaximumIncrement * TIMER_TABLE_SIZE)
  129. ;
  130. mov eax, ecx
  131. mul [_KiUpperModMul]
  132. add ebx, eax
  133. adc edx, 0
  134. mov ecx, edx
  135. je Upper_zero
  136. jmp slow_resume
  137. ;
  138. ; We need to recalculate the slot zero time. We do this
  139. ; by calculating the remainder of the current time mod (KeMaximumIncrement*TIMER_TABLE_SIZE).
  140. ; By subtracting this remainder from the current time we know the slot number must be zero.
  141. ;
  142. recalc_slotzero:
  143. mov eax, CurrentTime + 4
  144. xor edx, edx
  145. div [_KeTimerReductionModulus]
  146. mov eax, CurrentTime
  147. div [_KeTimerReductionModulus]
  148. ;
  149. ; edx now contains the remainder of the divide. We can calculate a slot
  150. ; zero time by subtracting the remainder from current time.
  151. ;
  152. mov eax, CurrentTime
  153. sub eax, edx
  154. mov edx, CurrentTime+4
  155. sbb edx, 0
  156. ;
  157. ; Never store a negative slot time. By avoiding this we eliminate the need to check
  158. ; for overflow in the fast path above. We can only overflow and have a result of zero
  159. ; with a high order time byte of 0xffffffff.
  160. ;
  161. js slow_resume
  162. mov [_KiSlotZeroTime], eax
  163. mov [_KiSlotZeroTime+4], edx
  164. jmp slow_resume
  165. ;
  166. ; If we underflow whe we subtract the slot zero time then interupt time has gone backwards.
  167. ; We have to correct for the missing 2^64 bit.
  168. ;
  169. underflow:
  170. ;
  171. ; Clear out the slot zero time so it will be recalculated
  172. ;
  173. and dword ptr [_KiSlotZeroTime], 0
  174. and dword ptr [_KiSlotZeroTime+4], 0
  175. @@: add ecx, [_KiUpperModMul]
  176. jnc underflow_return
  177. jmp @b
  178. stdENDP _KiComputeTimerTableIndex
  179. _TEXT$00 ends
  180. end