Changeset 32572 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Sep 16, 2010 4:18:12 PM (14 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r32529 r32572 1390 1390 generic/RTLogWriteStdErr-stub-generic.cpp \ 1391 1391 generic/RTLogWriteUser-generic.cpp \ 1392 generic/RTMpGetArraySize-generic.cpp \ 1392 1393 generic/RTRandAdvCreateSystemFaster-generic.cpp \ 1393 1394 generic/uuid-generic.cpp \ -
trunk/src/VBox/Runtime/generic/timer-generic.cpp
r32504 r32572 87 87 88 88 89 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, u nsignedfFlags, PFNRTTIMER pfnTimer, void *pvUser)89 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser) 90 90 { 91 91 *ppTimer = NULL; … … 225 225 } 226 226 RT_EXPORT_SYMBOL(RTTimerStop); 227 228 229 RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) 230 { 231 if (!rtTimerIsValid(pTimer)) 232 return VERR_INVALID_HANDLE; 233 return VERR_NOT_SUPPORTED; 234 } 235 RT_EXPORT_SYMBOL(RTTimerChangeInterval); 227 236 228 237 -
trunk/src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c
r32504 r32572 90 90 91 91 92 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, u nsignedfFlags, PFNRTTIMER pfnTimer, void *pvUser)92 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser) 93 93 { 94 94 *ppTimer = NULL; … … 102 102 && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL 103 103 && (fFlags & RTTIMER_FLAGS_CPU_MASK) > mp_maxid) 104 return VERR_ INVALID_PARAMETER;104 return VERR_CPU_NOT_FOUND; 105 105 106 106 /* … … 166 166 if (!pTimer->fSuspended) 167 167 return VERR_TIMER_ACTIVE; 168 if ( pTimer->fSpecificCpu 169 && !RTMpIsCpuOnline(pTimer->idCpu)) 170 return VERR_CPU_OFFLINE; 168 171 169 172 /* … … 199 202 200 203 return VINF_SUCCESS; 204 } 205 206 207 RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) 208 { 209 if (!rtTimerIsValid(pTimer)) 210 return VERR_INVALID_HANDLE; 211 return VERR_NOT_SUPPORTED; 201 212 } 202 213 -
trunk/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c
r32504 r32572 5 5 6 6 /* 7 * Copyright (C) 2006-20 08Oracle Corporation7 * Copyright (C) 2006-2010 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 44 44 #include "internal/magics.h" 45 45 46 /* We use the API of Linux 2.6.28+ (hrtimer_add_expires_ns()) */ 47 #if !defined(RT_USE_LINUX_HRTIMER) \ 48 && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) \ 46 /** @def RTTIMER_LINUX_HAVE_HRTIMER 47 * Whether the kernel support high resolution timers (Linux kernel versions 48 * 2.6.28 and later (hrtimer_add_expires_ns()). */ 49 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) 50 # define RTTIMER_LINUX_HAVE_HRTIMER 51 #endif 52 53 /** @def RTTIMER_LINUX_ONLY_HRTIMER 54 * Whether to use high resolution timers for everything or not. Implies 55 * RTTIMER_LINUX_WITH_HRTIMER. */ 56 #if !defined(RTTIMER_LINUX_ONLY_HRTIMER) \ 57 && defined(RTTIMER_LINUX_HAVE_HRTIMER) \ 49 58 && 0 /* currently disabled */ 50 # define RT _USE_LINUX_HRTIMER59 # define RTTIMER_LINUX_ONLY_HRTIMER 51 60 #endif 52 61 53 62 /* This check must match the ktime usage in rtTimeGetSystemNanoTS() / time-r0drv-linux.c. */ 54 #if defined(RT_USE_LINUX_HRTIMER) \ 55 && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) 56 # error "RT_USE_LINUX_HRTIMER requires 2.6.28 or later, sorry." 63 #if defined(RTTIMER_LINUX_ONLY_HRTIMER) \ 64 && !defined(RTTIMER_LINUX_HAVE_HRTIMER) 65 # error "RTTIMER_LINUX_ONLY_HRTIMER requires 2.6.28 or later, sorry." 66 #endif 67 68 /** @def RTTIMER_LINUX_WITH_HRTIMER 69 * Whether to use high resolution timers. */ 70 #if !defined(RTTIMER_LINUX_WITH_HRTIMER) \ 71 && defined(RTTIMER_LINUX_HAVE_HRTIMER) 72 # define RTTIMER_LINUX_WITH_HRTIMER 57 73 #endif 58 74 … … 96 112 typedef struct RTTIMERLNXSUBTIMER 97 113 { 98 /** The linux timer structure. */ 99 #ifdef RT_USE_LINUX_HRTIMER 100 struct hrtimer LnxTimer; 101 #else 102 struct timer_list LnxTimer; 103 /** The start of the current run (ns). 104 * This is used to calculate when the timer ought to fire the next time. */ 105 uint64_t u64StartTS; 106 /** The start of the current run (ns). 107 * This is used to calculate when the timer ought to fire the next time. */ 108 uint64_t u64NextTS; 109 #endif 110 /** The current tick number (since u64StartTS). */ 114 /** Timer specific data. */ 115 union 116 { 117 #if defined(RTTIMER_LINUX_WITH_HRTIMER) 118 /** High resolution timer. */ 119 struct 120 { 121 /** The linux timer structure. */ 122 struct hrtimer LnxTimer; 123 } Hr; 124 #endif 125 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 126 /** Standard timer. */ 127 struct 128 { 129 /** The linux timer structure. */ 130 struct timer_list LnxTimer; 131 /** The start of the current run (ns). 132 * This is used to calculate when the timer ought to fire the next time. */ 133 uint64_t u64StartTS; 134 /** The start of the current run (ns). 135 * This is used to calculate when the timer ought to fire the next time. */ 136 uint64_t u64NextTS; 137 /** The u64NextTS in jiffies. */ 138 unsigned long ulNextJiffies; 139 } Std; 140 #endif 141 } u; 142 /** The current tick number (since u.Std.u64StartTS). */ 111 143 uint64_t iTick; 112 144 /** Pointer to the parent timer. */ 113 145 PRTTIMER pParent; 114 #ifndef RT_USE_LINUX_HRTIMER115 /** The u64NextTS in jiffies. */116 unsigned long ulNextJiffies;117 #endif118 146 /** The current sub-timer state. */ 119 147 RTTIMERLNXSTATE volatile enmState; … … 121 149 /** Pointer to a linux sub-timer. */ 122 150 typedef RTTIMERLNXSUBTIMER *PRTTIMERLNXSUBTIMER; 123 AssertCompileMemberOffset(RTTIMERLNXSUBTIMER, LnxTimer, 0);124 151 125 152 … … 144 171 bool fAllCpus; 145 172 #endif /* else: All -> specific on non-SMP kernels */ 146 /** The CPU it must run on if fSpecificCpu is set. */ 173 /** Whether it is a high resolution timer or a standard one. */ 174 bool fHighRes; 175 /** The id of the CPU it must run on if fSpecificCpu is set. */ 147 176 RTCPUID idCpu; 148 177 /** The number of CPUs this timer should run on. */ … … 153 182 void *pvUser; 154 183 /** The timer interval. 0 if one-shot. */ 155 uint64_t 156 #ifndef RT _USE_LINUX_HRTIMER184 uint64_t volatile u64NanoInterval; 185 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 157 186 /** This is set to the number of jiffies between ticks if the interval is 158 187 * an exact number of jiffies. */ … … 210 239 } 211 240 212 213 #ifdef RT_USE_LINUX_HRTIMER 241 #ifdef RTTIMER_LINUX_WITH_HRTIMER 242 214 243 /** 215 244 * Converts a nano second time stamp to ktime_t. … … 239 268 } 240 269 241 #else /* ! RT_USE_LINUX_HRTIMER */ 242 270 #endif /* RTTIMER_LINUX_WITH_HRTIMER */ 271 272 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 243 273 /** 244 274 * Converts a nano second interval to jiffies. … … 258 288 return (cNanoSecs + (TICK_NSEC-1)) / TICK_NSEC; 259 289 } 260 #endif /* ! RT_USE_LINUX_HRTIMER */290 #endif /* !RTTIMER_LINUX_ONLY_HRTIMER */ 261 291 262 292 … … 269 299 * @param fPinned true = timer pinned to a specific CPU, 270 300 * false = timer can migrate between CPUs 271 */ 272 static void rtTimerLnxStartSubTimer(PRTTIMERLNXSUBTIMER pSubTimer, uint64_t u64Now, uint64_t u64First, bool fPinned) 301 * @param fHighRes Whether the user requested a high resolution timer or not. 302 */ 303 static void rtTimerLnxStartSubTimer(PRTTIMERLNXSUBTIMER pSubTimer, uint64_t u64Now, uint64_t u64First, 304 bool fPinned, bool fHighRes) 273 305 { 274 306 /* … … 276 308 */ 277 309 uint64_t u64NextTS = u64Now + u64First; 278 #ifndef RT_USE_LINUX_HRTIMER 279 pSubTimer->u64StartTS = u64NextTS; 280 pSubTimer->u64NextTS = u64NextTS; 310 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 311 if (fHighRes) 312 { 313 pSubTimer->u.Std.u64StartTS = u64NextTS; 314 pSubTimer->u.Std.u64NextTS = u64NextTS; 315 } 281 316 #endif 282 317 283 318 pSubTimer->iTick = 0; 284 319 285 #ifdef RT_USE_LINUX_HRTIMER 286 hrtimer_start(&pSubTimer->LnxTimer, rtTimerLnxNanoToKt(u64NextTS), 287 fPinned ? HRTIMER_MODE_ABS_PINNED : HRTIMER_MODE_ABS); 288 #else 320 #ifdef RTTIMER_LINUX_WITH_HRTIMER 321 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 322 if (fHighRes) 323 # endif 324 hrtimer_start(&pSubTimer->u.Hr.LnxTimer, rtTimerLnxNanoToKt(u64NextTS), 325 fPinned ? HRTIMER_MODE_ABS_PINNED : HRTIMER_MODE_ABS); 326 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 327 else 328 # endif 329 #endif 330 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 289 331 { 290 332 unsigned long cJiffies = !u64First ? 0 : rtTimerLnxNanoToJiffies(u64First); 291 pSubTimer->u lNextJiffies = jiffies + cJiffies;333 pSubTimer->u.Std.ulNextJiffies = jiffies + cJiffies; 292 334 # ifdef CONFIG_SMP 293 335 if (fPinned) 294 mod_timer_pinned(&pSubTimer-> LnxTimer, pSubTimer->ulNextJiffies);336 mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies); 295 337 else 296 338 # endif 297 mod_timer(&pSubTimer-> LnxTimer, pSubTimer->ulNextJiffies);339 mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies); 298 340 } 299 341 #endif … … 310 352 static void rtTimerLnxStopSubTimer(PRTTIMERLNXSUBTIMER pSubTimer) 311 353 { 312 #ifdef RT_USE_LINUX_HRTIMER 313 hrtimer_cancel(&pSubTimer->LnxTimer); 314 #else 315 if (timer_pending(&pSubTimer->LnxTimer)) 316 del_timer_sync(&pSubTimer->LnxTimer); 354 #ifdef RTTIMER_LINUX_WITH_HRTIMER 355 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 356 if (pSubTimer->pParent->fHighRes) 357 # endif 358 hrtimer_cancel(&pSubTimer->u.Hr.LnxTimer); 359 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 360 else 361 # endif 362 #endif 363 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 364 { 365 if (timer_pending(&pSubTimer->u.Std.LnxTimer)) 366 del_timer_sync(&pSubTimer->u.Std.LnxTimer); 367 } 317 368 #endif 318 369 … … 321 372 322 373 323 #ifdef RT_USE_LINUX_HRTIMER 324 /** 325 * Timer callback function. 326 * @returns HRTIMER_NORESTART or HRTIMER_RESTART depending on whether it's a one-shot or interval timer. 374 #ifdef RTTIMER_LINUX_WITH_HRTIMER 375 /** 376 * Timer callback function for high resolution timers. 377 * 378 * @returns HRTIMER_NORESTART or HRTIMER_RESTART depending on whether it's a 379 * one-shot or interval timer. 327 380 * @param pHrTimer Pointer to the sub-timer structure. 328 381 */ 329 static enum hrtimer_restart rtTimerLinuxCallback(struct hrtimer *pHrTimer) 330 #else 331 /** 332 * Timer callback function. 333 * @param ulUser Address of the sub-timer structure. 334 */ 335 static void rtTimerLinuxCallback(unsigned long ulUser) 336 #endif 337 { 338 #ifdef RT_USE_LINUX_HRTIMER 339 enum hrtimer_restart rc; 340 PRTTIMERLNXSUBTIMER pSubTimer = (PRTTIMERLNXSUBTIMER)pHrTimer; 341 #else 342 PRTTIMERLNXSUBTIMER pSubTimer = (PRTTIMERLNXSUBTIMER)ulUser; 343 #endif 344 PRTTIMER pTimer = pSubTimer->pParent; 382 static enum hrtimer_restart rtTimerLinuxHrCallback(struct hrtimer *pHrTimer) 383 { 384 PRTTIMERLNXSUBTIMER pSubTimer = RT_FROM_MEMBER(pHrTimer, RTTIMERLNXSUBTIMER, u.Hr.LnxTimer); 385 PRTTIMER pTimer = pSubTimer->pParent; 386 enum hrtimer_restart rc; 345 387 346 388 /* … … 359 401 { 360 402 rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_ACTIVE); 361 # ifdef RT_USE_LINUX_HRTIMER362 403 rc = HRTIMER_NORESTART; 363 # endif364 404 } 365 405 else if (!pTimer->u64NanoInterval) … … 371 411 ASMAtomicWriteBool(&pTimer->fSuspended, true); 372 412 rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_ACTIVE); 373 #ifdef RT_USE_LINUX_HRTIMER374 413 rc = HRTIMER_NORESTART; 375 #else376 /* detached before we're called, nothing to do for this case. */377 #endif378 379 414 pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick); 380 415 } 381 416 else 382 417 { 418 /* 419 * Run the timer. Update the timer after calling the method. 420 */ 383 421 const uint64_t iTick = ++pSubTimer->iTick; 384 385 #ifdef RT_USE_LINUX_HRTIMER 386 hrtimer_add_expires_ns(&pSubTimer->LnxTimer, pTimer->u64NanoInterval); 387 rc = HRTIMER_RESTART; 388 #else 389 const uint64_t u64NanoTS = RTTimeNanoTS(); 390 422 pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick); 423 424 /** @todo Check reference counting wrt. RTTimerDestroy from the 425 * callback? */ 426 if ( pSubTimer->enmState == RTTIMERLNXSTATE_ACTIVE 427 || pSubTimer->enmState == RTTIMERLNXSTATE_MP_STARTING) 428 { 429 hrtimer_add_expires_ns(&pSubTimer->u.Hr.LnxTimer, ASMAtomicReadU64(&pTimer->u64NanoInterval)); 430 rc = HRTIMER_RESTART; 431 } 432 else 433 rc = HRTIMER_NORESTART; 434 } 435 436 return rc; 437 } 438 #endif /* RTTIMER_LINUX_ONLY_HRTIMER */ 439 440 441 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 442 /** 443 * Timer callback function for standard timers. 444 * 445 * @param ulUser Address of the sub-timer structure. 446 */ 447 static void rtTimerLinuxStdCallback(unsigned long ulUser) 448 { 449 PRTTIMERLNXSUBTIMER pSubTimer = (PRTTIMERLNXSUBTIMER)ulUser; 450 PRTTIMER pTimer = pSubTimer->pParent; 451 452 /* 453 * Don't call the handler if the timer has been suspended. 454 * Also, when running on all CPUS, make sure we don't call out twice 455 * on a CPU because of timer migration. 456 * 457 * For the specific cpu case, we're just ignoring timer migration for now... (bad) 458 */ 459 if ( ASMAtomicUoReadBool(&pTimer->fSuspended) 460 #ifdef CONFIG_SMP 461 || ( pTimer->fAllCpus 462 && (RTCPUID)(pSubTimer - &pTimer->aSubTimers[0]) != RTMpCpuId()) 463 #endif 464 ) 465 rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_ACTIVE); 466 else if (!pTimer->u64NanoInterval) 467 { 468 /* 469 * One shot timer, stop it before dispatching it. 470 */ 471 if (pTimer->cCpus == 1) 472 ASMAtomicWriteBool(&pTimer->fSuspended, true); 473 rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_STOPPED, RTTIMERLNXSTATE_ACTIVE); 474 pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick); 475 } 476 else 477 { 391 478 /* 392 479 * Interval timer, calculate the next timeout and re-arm it. 393 480 * 394 * The first time around, we'll re-adjust the u 64StartTS to481 * The first time around, we'll re-adjust the u.Std.u64StartTS to 395 482 * try prevent some jittering if we were started at a bad time. 396 483 * This may of course backfire with highres timers... 484 * 485 * Note! u64NanoInterval won't change for standard timers. 397 486 */ 487 const uint64_t iTick = ++pSubTimer->iTick; 488 const uint64_t u64NanoInterval = pTimer->u64NanoInterval; 489 const uint64_t u64NanoTS = RTTimeNanoTS(); 490 398 491 if (RT_UNLIKELY(iTick == 1)) 399 492 { 400 pSubTimer->u64StartTS = pSubTimer->u64NextTS = u64NanoTS; 401 pSubTimer->ulNextJiffies = jiffies; 493 pSubTimer->u.Std.u64StartTS = u64NanoTS; 494 pSubTimer->u.Std.u64NextTS = u64NanoTS; 495 pSubTimer->u.Std.ulNextJiffies = jiffies; 402 496 } 403 497 404 pSubTimer->u 64NextTS += pTimer->u64NanoInterval;498 pSubTimer->u.Std.u64NextTS += u64NanoInterval; 405 499 if (pTimer->cJiffies) 406 500 { 407 pSubTimer->u lNextJiffies += pTimer->cJiffies;501 pSubTimer->u.Std.ulNextJiffies += pTimer->cJiffies; 408 502 /* Prevent overflows when the jiffies counter wraps around. 409 503 * Special thanks to Ken Preslan for helping debugging! */ 410 while (time_before(pSubTimer->u lNextJiffies, jiffies))504 while (time_before(pSubTimer->u.Std.ulNextJiffies, jiffies)) 411 505 { 412 pSubTimer->u lNextJiffies += pTimer->cJiffies;413 pSubTimer->u 64NextTS += pTimer->u64NanoInterval;506 pSubTimer->u.Std.ulNextJiffies += pTimer->cJiffies; 507 pSubTimer->u.Std.u64NextTS += u64NanoInterval; 414 508 } 415 509 } 416 510 else 417 511 { 418 while (pSubTimer->u 64NextTS < u64NanoTS)419 pSubTimer->u 64NextTS += pTimer->u64NanoInterval;420 pSubTimer->u lNextJiffies = jiffies + rtTimerLnxNanoToJiffies(pSubTimer->u64NextTS - u64NanoTS);512 while (pSubTimer->u.Std.u64NextTS < u64NanoTS) 513 pSubTimer->u.Std.u64NextTS += u64NanoInterval; 514 pSubTimer->u.Std.ulNextJiffies = jiffies + rtTimerLnxNanoToJiffies(pSubTimer->u.Std.u64NextTS - u64NanoTS); 421 515 } 422 516 423 517 # ifdef CONFIG_SMP 424 518 if (pTimer->fSpecificCpu || pTimer->fAllCpus) 425 mod_timer_pinned(&pSubTimer-> LnxTimer, pSubTimer->ulNextJiffies);519 mod_timer_pinned(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies); 426 520 else 427 521 # endif 428 mod_timer(&pSubTimer->LnxTimer, pSubTimer->ulNextJiffies); 429 #endif 522 mod_timer(&pSubTimer->u.Std.LnxTimer, pSubTimer->u.Std.ulNextJiffies); 430 523 431 524 /* … … 434 527 pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick); 435 528 } 436 437 #ifdef RT_USE_LINUX_HRTIMER 438 return rc; 439 #endif 440 } 529 } 530 #endif /* !RTTIMER_LINUX_ONLY_HRTIMER */ 531 441 532 442 533 … … 455 546 PRTTIMER pTimer = (PRTTIMER)pvUser1; 456 547 Assert(idCpu < pTimer->cCpus); 457 rtTimerLnxStartSubTimer(&pTimer->aSubTimers[idCpu], pArgs->u64Now, pArgs->u64First, true /*fPinned*/ );548 rtTimerLnxStartSubTimer(&pTimer->aSubTimers[idCpu], pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes); 458 549 } 459 550 … … 607 698 PRTTIMERLNXSUBTIMER pSubTimer = &pTimer->aSubTimers[idCpu]; 608 699 if (rtTimerLnxCmpXchgState(&pSubTimer->enmState, RTTIMERLNXSTATE_MP_STARTING, RTTIMERLNXSTATE_STOPPED)) 609 rtTimerLnxStartSubTimer(pSubTimer, pArgs->u64Now, pArgs->u64First, true /*fPinned*/ );700 rtTimerLnxStartSubTimer(pSubTimer, pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes); 610 701 } 611 702 … … 660 751 661 752 if (RTMpCpuId() == idCpu) 662 rtTimerLnxStartSubTimer(pSubTimer, Args.u64Now, Args.u64First, true /*fPinned*/ );753 rtTimerLnxStartSubTimer(pSubTimer, Args.u64Now, Args.u64First, true /*fPinned*/, pTimer->fHighRes); 663 754 else 664 755 { … … 708 799 PRTTIMERLINUXSTARTONCPUARGS pArgs = (PRTTIMERLINUXSTARTONCPUARGS)pvUser2; 709 800 PRTTIMER pTimer = (PRTTIMER)pvUser1; 710 rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], pArgs->u64Now, pArgs->u64First, true /*fPinned*/ );801 rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], pArgs->u64Now, pArgs->u64First, true /*fPinned*/, pTimer->fHighRes); 711 802 } 712 803 … … 742 833 ASMAtomicWriteBool(&pTimer->fSuspended, false); 743 834 if (!pTimer->fSpecificCpu) 744 rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], Args.u64Now, Args.u64First, false /*fPinned*/); 835 { 836 rtTimerLnxStartSubTimer(&pTimer->aSubTimers[0], Args.u64Now, Args.u64First, false /*fPinned*/, pTimer->fHighRes); 837 } 745 838 else 746 839 { … … 792 885 793 886 887 RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) 888 { 889 int rc = VINF_SUCCESS; 890 891 /* 892 * Validate. 893 */ 894 AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); 895 AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); 896 AssertReturn(u64NanoInterval, VERR_INVALID_PARAMETER); 897 898 /* 899 * Make the change. 900 */ 901 #ifdef RTTIMER_LINUX_WITH_HRTIMER 902 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 903 if (pTimer->fHighRes) 904 # endif 905 ASMAtomicWriteU64(&pTimer->u64NanoInterval, u64NanoInterval); 906 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 907 else 908 # endif 909 #endif 910 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 911 rc = VERR_NOT_SUPPORTED; /** @todo Implement this if needed. */ 912 #endif 913 914 return rc; 915 } 916 RT_EXPORT_SYMBOL(RTTimerChangeInterval); 917 918 794 919 RTDECL(int) RTTimerDestroy(PRTTIMER pTimer) 795 920 { … … 836 961 837 962 838 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, u nsignedfFlags, PFNRTTIMER pfnTimer, void *pvUser)839 { 840 PRTTIMER pTimer;841 RTCPUID iCpu;842 unsigned cCpus;963 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser) 964 { 965 PRTTIMER pTimer; 966 RTCPUID iCpu; 967 unsigned cCpus; 843 968 844 969 *ppTimer = NULL; … … 851 976 if ( (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) 852 977 && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL 853 && !RTMpIsCpuOnline(fFlags & RTTIMER_FLAGS_CPU_MASK)) 854 return (fFlags & RTTIMER_FLAGS_CPU_MASK) > RTMpGetMaxCpuId() 855 ? VERR_CPU_NOT_FOUND 856 : VERR_CPU_OFFLINE; 978 && !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK))) 979 return VERR_CPU_NOT_FOUND; 857 980 858 981 /* … … 879 1002 pTimer->hSpinlock = NIL_RTSPINLOCK; 880 1003 pTimer->fSuspended = true; 1004 pTimer->fHighRes = !!(fFlags & RTTIMER_FLAGS_HIGH_RES); 881 1005 #ifdef CONFIG_SMP 882 1006 pTimer->fSpecificCpu = (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL; 883 1007 pTimer->fAllCpus = (fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL; 884 pTimer->idCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;1008 pTimer->idCpu = pTimer->fSpecificCpu ? RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK) : NIL_RTCPUID; 885 1009 #else 886 1010 pTimer->fSpecificCpu = !!(fFlags & RTTIMER_FLAGS_CPU_SPECIFIC); … … 891 1015 pTimer->pvUser = pvUser; 892 1016 pTimer->u64NanoInterval = u64NanoInterval; 893 #ifndef RT _USE_LINUX_HRTIMER1017 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 894 1018 pTimer->cJiffies = u64NanoInterval / RTTimerGetSystemGranularity(); 895 1019 if (pTimer->cJiffies * RTTimerGetSystemGranularity() != u64NanoInterval) … … 899 1023 for (iCpu = 0; iCpu < cCpus; iCpu++) 900 1024 { 901 #ifdef RT_USE_LINUX_HRTIMER 902 hrtimer_init(&pTimer->aSubTimers[iCpu].LnxTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 903 pTimer->aSubTimers[iCpu].LnxTimer.function = rtTimerLinuxCallback; 904 #else 905 init_timer(&pTimer->aSubTimers[iCpu].LnxTimer); 906 pTimer->aSubTimers[iCpu].LnxTimer.data = (unsigned long)&pTimer->aSubTimers[iCpu]; 907 pTimer->aSubTimers[iCpu].LnxTimer.function = rtTimerLinuxCallback; 908 pTimer->aSubTimers[iCpu].LnxTimer.expires = jiffies; 909 pTimer->aSubTimers[iCpu].u64StartTS = 0; 910 pTimer->aSubTimers[iCpu].u64NextTS = 0; 1025 #ifdef RTTIMER_LINUX_WITH_HRTIMER 1026 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 1027 if (pTimer->fHighRes) 1028 # endif 1029 { 1030 hrtimer_init(&pTimer->aSubTimers[iCpu].u.Hr.LnxTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 1031 pTimer->aSubTimers[iCpu].u.Hr.LnxTimer.function = rtTimerLinuxHrCallback; 1032 } 1033 # ifndef RTTIMER_LINUX_ONLY_HRTIMER 1034 else 1035 # endif 1036 #endif 1037 #ifndef RTTIMER_LINUX_ONLY_HRTIMER 1038 { 1039 init_timer(&pTimer->aSubTimers[iCpu].u.Std.LnxTimer); 1040 pTimer->aSubTimers[iCpu].u.Std.LnxTimer.data = (unsigned long)&pTimer->aSubTimers[iCpu]; 1041 pTimer->aSubTimers[iCpu].u.Std.LnxTimer.function = rtTimerLinuxStdCallback; 1042 pTimer->aSubTimers[iCpu].u.Std.LnxTimer.expires = jiffies; 1043 pTimer->aSubTimers[iCpu].u.Std.u64StartTS = 0; 1044 pTimer->aSubTimers[iCpu].u.Std.u64NextTS = 0; 1045 } 911 1046 #endif 912 1047 pTimer->aSubTimers[iCpu].iTick = 0; … … 945 1080 RTDECL(uint32_t) RTTimerGetSystemGranularity(void) 946 1081 { 947 #ifdef RT_USE_LINUX_HRTIMER 1082 #ifdef RTTIMER_LINUX_ONLY_HRTIMER 1083 /** @todo Not sure if this is what we want or not... Add new API for 1084 * querying the resolution of the high res timers? */ 948 1085 struct timespec Ts; 949 1086 int rc = hrtimer_get_res(CLOCK_MONOTONIC, &Ts); … … 975 1112 RTDECL(bool) RTTimerCanDoHighResolution(void) 976 1113 { 977 #ifdef RT _USE_LINUX_HRTIMER1114 #ifdef RTTIMER_LINUX_WITH_HRTIMER 978 1115 return true; 979 1116 #else -
trunk/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
r32504 r32572 218 218 if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) 219 219 return VERR_TIMER_ACTIVE; 220 if ( pTimer->fSpecificCpu 221 && !RTMpIsCpuOnline(pTimer->idCpu)) 222 return VERR_CPU_OFFLINE; 220 223 221 224 /* … … 291 294 292 295 296 RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) 297 { 298 AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); 299 AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); 300 301 return VERR_NOT_SUPPORTED; 302 } 303 304 293 305 RTDECL(int) RTTimerDestroy(PRTTIMER pTimer) 294 306 { … … 300 312 301 313 /* 302 * Invalidate the timer, stop it if it's running and finally .314 * Invalidate the timer, stop it if it's running and finally 303 315 * free up the memory. 304 316 */ … … 312 324 313 325 314 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, u nsignedfFlags, PFNRTTIMER pfnTimer, void *pvUser)326 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser) 315 327 { 316 328 *ppTimer = NULL; … … 323 335 if ( (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) 324 336 && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL 325 && !RTMpIsCpuOnline(fFlags & RTTIMER_FLAGS_CPU_MASK)) 326 return (fFlags & RTTIMER_FLAGS_CPU_MASK) > RTMpGetMaxCpuId() 327 ? VERR_CPU_NOT_FOUND 328 : VERR_CPU_OFFLINE; 337 && !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK))) 338 return VERR_CPU_NOT_FOUND; 329 339 330 340 /* … … 349 359 pTimer->fSpecificCpu = (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL; 350 360 pTimer->fOmniTimer = (fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL; 351 pTimer->idCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;361 pTimer->idCpu = pTimer->fSpecificCpu ? RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK) : NIL_RTCPUID; 352 362 pTimer->cSubTimers = cSubTimers; 353 363 pTimer->pfnTimer = pfnTimer; … … 362 372 * ASSUMES that no cpus will ever go offline. 363 373 */ 364 pTimer->idCpu = NIL_RTCPUID; /* */374 pTimer->idCpu = NIL_RTCPUID; 365 375 for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++) 366 376 { -
trunk/src/VBox/Runtime/r0drv/os2/timer-r0drv-os2.cpp
r32504 r32572 109 109 110 110 111 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, u nsignedfFlags, PFNRTTIMER pfnTimer, void *pvUser)111 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser) 112 112 { 113 113 *ppTimer = NULL; … … 289 289 290 290 291 RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) 292 { 293 if (!rtTimerIsValid(pTimer)) 294 return VERR_INVALID_HANDLE; 295 296 return VERR_NOT_SUPPORTED; 297 } 298 299 291 300 DECLASM(void) rtTimerOs2Tick(void) 292 301 { -
trunk/src/VBox/Runtime/r0drv/solaris/vbi/timer-r0drv-solaris.c
r32504 r32572 103 103 104 104 105 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, u nsignedfFlags, PFNRTTIMER pfnTimer, void *pvUser)105 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser) 106 106 { 107 107 RT_ASSERT_PREEMPTIBLE(); … … 118 118 if ( (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) 119 119 && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL 120 && !RTMpIsCpuPossible( (fFlags & RTTIMER_FLAGS_CPU_MASK)))120 && !RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(fFlags & RTTIMER_FLAGS_CPU_MASK))) 121 121 return VERR_CPU_NOT_FOUND; 122 122 … … 143 143 pTimer->fAllCpu = false; 144 144 pTimer->fSpecificCpu = true; 145 pTimer->iCpu = fFlags & RTTIMER_FLAGS_CPU_MASK; 145 pTimer->iCpu = fFlags & RTTIMER_FLAGS_CPU_MASK; /* ASSUMES: index == cpuid */ 146 146 } 147 147 else … … 237 237 238 238 239 RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) 240 { 241 RTTIMER_ASSERT_VALID_RET(pTimer); 242 243 /** @todo implement me! */ 244 245 return VERR_NOT_SUPPORTED; 246 } 247 248 239 249 RTDECL(uint32_t) RTTimerGetSystemGranularity(void) 240 250 { … … 257 267 RTDECL(bool) RTTimerCanDoHighResolution(void) 258 268 { 259 return true; 260 } 261 269 /** @todo return true; - when missing bits have been implemented and tested*/ 270 return false; 271 } 272 -
trunk/src/VBox/Runtime/r3/posix/timer-posix.cpp
r28800 r32572 397 397 398 398 399 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, u nsignedfFlags, PFNRTTIMER pfnTimer, void *pvUser)399 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser) 400 400 { 401 401 /* … … 811 811 } 812 812 813 814 RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) 815 { 816 AssertPtrReturn(pTimer, VERR_INVALID_POINTER); 817 AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_MAGIC); 818 return VERR_NOT_SUPPORTED; 819 } 820
Note:
See TracChangeset
for help on using the changeset viewer.