Changeset 9466 in vbox for trunk/src/VBox/Runtime/r0drv/linux
- Timestamp:
- Jun 6, 2008 11:44:27 AM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 31723
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
r9444 r9466 108 108 /** Pointer to the parent timer. */ 109 109 PRTTIMER pParent; 110 #ifndef RT_USE_LINUX_HRTIMER 111 /** The u64NextTS in jiffies. */ 112 unsigned long ulNextJiffies; 113 #endif 110 114 /** The current sub-timer state. */ 111 115 RTTIMERLNXSTATE volatile enmState; … … 146 150 /** The timer interval. 0 if one-shot. */ 147 151 uint64_t u64NanoInterval; 152 #ifndef RT_USE_LINUX_HRTIMER 153 /** This is set to the number of jiffies between ticks if the interval is 154 * an exact number of jiffies. */ 155 unsigned long cJiffies; 156 #endif 148 157 /** Sub-timers. 149 158 * Normally there is just one, but for RTTIMER_FLAGS_CPU_ALL this will contain … … 195 204 196 205 197 #ifndef RT_USE_LINUX_HRTIMER 206 #ifdef RT_USE_LINUX_HRTIMER 207 /** 208 * Converts a nano second time stamp to ktime_t. 209 * 210 * ASSUMES RTTimeNanoTS() is implemented using ktime_get_ts(). 211 * 212 * @returns ktime_t. 213 * @param cNanoSecs Nanoseconds. 214 */ 215 DECLINLINE(ktime_t) rtTimerLnxNanoToKt(uint64_t cNanoSecs) 216 { 217 /* With some luck the compiler optimizes the division out of this... (Bet it doesn't.) */ 218 return ktime_set(cNanoSecs / 1000000000, cNanoSecs % 1000000000); 219 } 220 221 /** 222 * Converts ktime_t to a nano second time stamp. 223 * 224 * ASSUMES RTTimeNanoTS() is implemented using ktime_get_ts(). 225 * 226 * @returns nano second time stamp. 227 * @param Kt ktime_t. 228 */ 229 DECLINLINE(uint64_t) rtTimerLnxKtToNano(ktime_t Kt) 230 { 231 return ktime_to_ns(Kt); 232 } 233 234 #else /* ! RT_USE_LINUX_HRTIMER */ 235 198 236 /** 199 237 * Converts a nano second interval to jiffies. … … 234 272 235 273 #ifdef RT_USE_LINUX_HRTIMER 236 { 237 /* ASSUMES RTTimeNanoTS() is implemented using ktime_get_ts(). */ 238 struct timespec Ts; 239 ktime_t Kt; 240 Ts.tv_sec = u64NextTS / 1000000000; 241 Ts.tv_nsec = u64NextTS % 1000000000; 242 Kt = timespec_to_ktime(Ts); 243 hrtimer_start(&pSubTimer->LnxTimer, Kt, HRTIMER_MODE_ABS); 244 } 274 hrtimer_start(&pSubTimer->LnxTimer, rtTimerLnxNanoToKt(u64NextTS), HRTIMER_MODE_ABS); 245 275 #else 246 276 { 247 277 unsigned long cJiffies = !u64First ? 0 : rtTimerLnxNanoToJiffies(u64First); 248 mod_timer(&pSubTimer->LnxTimer, jiffies + cJiffies); 278 pSubTimer->ulNextJiffies = jiffies + cJiffies; 279 mod_timer(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies); 249 280 } 250 281 #endif … … 341 372 const uint64_t u64NanoTS = RTTimeNanoTS(); 342 373 const uint64_t iTick = ++pSubTimer->iTick; 343 #ifdef RT_USE_LINUX_HRTIMER 344 if (iTick == 1) 345 pSubTimer->u64StartTS = u64NanoTS; 346 #endif 347 pSubTimer->u64NextTS = pSubTimer->u64StartTS 348 + iTick * pTimer->u64NanoInterval; 349 if (pSubTimer->u64NextTS < u64NanoTS) 350 pSubTimer->u64NextTS = u64NanoTS + RTTimerGetSystemGranularity() / 2; 351 352 #ifdef RT_USE_LINUX_HRTIMER 374 375 if (RT_UNLIKELY(iTick == 1)) 353 376 { 354 /* ASSUMES RTTimeNanoTS() is implemented using ktime_get_ts(). */ 355 struct timespec Ts;356 Ts.tv_sec = pSubTimer->u64NextTS / 1000000000; 357 Ts.tv_nsec = pSubTimer->u64NextTS % 1000000000;358 pSubTimer-> LnxTimer.expires = timespec_to_ktime(Ts);359 rc = HRTIMER_RESTART; 377 #ifdef RT_USE_LINUX_HRTIMER 378 pSubTimer->u64StartTS = pSubTimer->u64NextTS = u64NanoTS;//rtTimerLnxKtToNano(pSubTimer->LnxTimer.base->softirq_time); 379 #else 380 pSubTimer->u64StartTS = pSubTimer->u64NextTS = u64NanoTS; 381 pSubTimer->ulNextJiffies = jiffies; 382 #endif 360 383 } 361 #else 384 385 pSubTimer->u64NextTS += pTimer->u64NanoInterval; 386 387 #ifdef RT_USE_LINUX_HRTIMER 388 while (pSubTimer->u64NextTS < u64NanoTS) 389 pSubTimer->u64NextTS += pTimer->u64NanoInterval; 390 391 pSubTimer->LnxTimer.expires = rtTimerLnxNanoToKt(pSubTimer->u64NextTS); 392 rc = HRTIMER_RESTART; 393 #else 394 if (pTimer->cJiffies) 362 395 { 363 uint64_t offDelta = pSubTimer->u64NextTS - u64NanoTS; 364 unsigned long cJiffies = rtTimerLnxNanoToJiffies(offDelta); 365 mod_timer(&pSubTimer->LnxTimer, jiffies + cJiffies); 396 pSubTimer->ulNextJiffies += pTimer->cJiffies; 397 while (pSubTimer->ulNextJiffies < jiffies) 398 { 399 pSubTimer->ulNextJiffies += pTimer->cJiffies; 400 pSubTimer->u64NextTS += pTimer->u64NanoInterval; 401 } 366 402 } 403 else 404 { 405 while (pSubTimer->u64NextTS < u64NanoTS) 406 pSubTimer->u64NextTS += pTimer->u64NanoInterval; 407 pSubTimer->ulNextJiffies = jiffies + rtTimerLnxNanoToJiffies(pSubTimer->u64NextTS - u64NanoTS); 408 } 409 410 mod_timer(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies); 367 411 #endif 368 412 … … 826 870 pTimer->pvUser = pvUser; 827 871 pTimer->u64NanoInterval = u64NanoInterval; 872 #ifndef RT_USE_LINUX_HRTIMER 873 pTimer->cJiffies = u64NanoInterval / RTTimerGetSystemGranularity(); 874 if (pTimer->cJiffies * RTTimerGetSystemGranularity() != u64NanoInterval) 875 pTimer->cJiffies = 0; 876 #endif 828 877 829 878 for (iCpu = 0; iCpu < cCpus; iCpu++) … … 875 924 { 876 925 #ifdef RT_USE_LINUX_HRTIMER 877 /** @todo later... */ 926 struct timespec Ts; 927 int rc = hrtimer_get_res(CLOCK_MONOTONIC, &Ts); 928 if (!rc) 929 { 930 Assert(!Ts.tv_sec); 931 return Ts.tv_nsec; 932 } 878 933 return 1000000000 / HZ; /* ns */ 879 934 #else
Note:
See TracChangeset
for help on using the changeset viewer.