| 453 | } |
| 454 | |
| 455 | void |
| 456 | hardclock(int cnt, int usermode) |
| 457 | { |
| 458 | struct pstats *pstats; |
| 459 | struct thread *td = curthread; |
| 460 | struct proc *p = td->td_proc; |
| 461 | int *t = DPCPU_PTR(pcputicks); |
| 462 | int global, i, newticks; |
| 463 | |
| 464 | /* |
| 465 | * Update per-CPU and possibly global ticks values. |
| 466 | */ |
| 467 | *t += cnt; |
| 468 | global = ticks; |
| 469 | do { |
| 470 | newticks = *t - global; |
| 471 | if (newticks <= 0) { |
| 472 | if (newticks < -1) |
| 473 | *t = global - 1; |
| 474 | newticks = 0; |
| 475 | break; |
| 476 | } |
| 477 | } while (!atomic_fcmpset_int(&ticks, &global, *t)); |
| 478 | |
| 479 | /* |
| 480 | * Run current process's virtual and profile time, as needed. |
| 481 | */ |
| 482 | pstats = p->p_stats; |
| 483 | if (__predict_false( |
| 484 | timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) || |
| 485 | timevalisset(&pstats->p_timer[ITIMER_PROF].it_value))) |
| 486 | hardclock_itimer(td, pstats, cnt, usermode); |
| 487 | |
| 488 | #ifdef HWPMC_HOOKS |
| 489 | if (PMC_CPU_HAS_SAMPLES(PCPU_GET(cpuid))) |
| 490 | PMC_CALL_HOOK_UNLOCKED(curthread, PMC_FN_DO_SAMPLES, NULL); |
| 491 | if (td->td_intr_frame != NULL) |
| 492 | PMC_SOFT_CALL_TF( , , clock, hard, td->td_intr_frame); |
| 493 | #endif |
| 494 | /* We are in charge to handle this tick duty. */ |
| 495 | if (newticks > 0) { |
| 496 | tc_ticktock(newticks); |
| 497 | #ifdef DEVICE_POLLING |
| 498 | /* Dangerous and no need to call these things concurrently. */ |
| 499 | if (atomic_cmpset_acq_int(&devpoll_run, 0, 1)) { |
| 500 | /* This is very short and quick. */ |
| 501 | hardclock_device_poll(); |
| 502 | atomic_store_rel_int(&devpoll_run, 0); |
| 503 | } |
| 504 | #endif /* DEVICE_POLLING */ |
| 505 | if (watchdog_enabled > 0) { |
| 506 | i = atomic_fetchadd_int(&watchdog_ticks, -newticks); |
| 507 | if (i > 0 && i <= newticks) |
| 508 | watchdog_fire(); |
| 509 | } |
| 510 | intr_event_handle(clk_intr_event, NULL); |
| 511 | } |
| 512 | if (curcpu == CPU_FIRST()) |
no test coverage detected