* Handle a stathz tick. This is really only relevant for timeshare * threads. */
| 2400 | * threads. |
| 2401 | */ |
| 2402 | void |
| 2403 | sched_clock(struct thread *td, int cnt) |
| 2404 | { |
| 2405 | struct tdq *tdq; |
| 2406 | struct td_sched *ts; |
| 2407 | |
| 2408 | THREAD_LOCK_ASSERT(td, MA_OWNED); |
| 2409 | tdq = TDQ_SELF(); |
| 2410 | #ifdef SMP |
| 2411 | /* |
| 2412 | * We run the long term load balancer infrequently on the first cpu. |
| 2413 | */ |
| 2414 | if (balance_tdq == tdq && smp_started != 0 && rebalance != 0 && |
| 2415 | balance_ticks != 0) { |
| 2416 | balance_ticks -= cnt; |
| 2417 | if (balance_ticks <= 0) |
| 2418 | sched_balance(); |
| 2419 | } |
| 2420 | #endif |
| 2421 | /* |
| 2422 | * Save the old switch count so we have a record of the last ticks |
| 2423 | * activity. Initialize the new switch count based on our load. |
| 2424 | * If there is some activity seed it to reflect that. |
| 2425 | */ |
| 2426 | tdq->tdq_oldswitchcnt = tdq->tdq_switchcnt; |
| 2427 | tdq->tdq_switchcnt = tdq->tdq_load; |
| 2428 | /* |
| 2429 | * Advance the insert index once for each tick to ensure that all |
| 2430 | * threads get a chance to run. |
| 2431 | */ |
| 2432 | if (tdq->tdq_idx == tdq->tdq_ridx) { |
| 2433 | tdq->tdq_idx = (tdq->tdq_idx + 1) % RQ_NQS; |
| 2434 | if (TAILQ_EMPTY(&tdq->tdq_timeshare.rq_queues[tdq->tdq_ridx])) |
| 2435 | tdq->tdq_ridx = tdq->tdq_idx; |
| 2436 | } |
| 2437 | ts = td_get_sched(td); |
| 2438 | sched_pctcpu_update(ts, 1); |
| 2439 | if ((td->td_pri_class & PRI_FIFO_BIT) || TD_IS_IDLETHREAD(td)) |
| 2440 | return; |
| 2441 | |
| 2442 | if (PRI_BASE(td->td_pri_class) == PRI_TIMESHARE) { |
| 2443 | /* |
| 2444 | * We used a tick; charge it to the thread so |
| 2445 | * that we can compute our interactivity. |
| 2446 | */ |
| 2447 | td_get_sched(td)->ts_runtime += tickincr * cnt; |
| 2448 | sched_interact_update(td); |
| 2449 | sched_priority(td); |
| 2450 | } |
| 2451 | |
| 2452 | /* |
| 2453 | * Force a context switch if the current thread has used up a full |
| 2454 | * time slice (default is 100ms). |
| 2455 | */ |
| 2456 | ts->ts_slice += cnt; |
| 2457 | if (ts->ts_slice >= tdq_slice(tdq)) { |
| 2458 | ts->ts_slice = 0; |
| 2459 | td->td_flags |= TDF_NEEDRESCHED | TDF_SLICEEND; |
no test coverage detected