Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_timeout.c
Show All 35 Lines | |||||
* From: @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 | * From: @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_callout_profiling.h" | #include "opt_callout_profiling.h" | ||||
#include "opt_ddb.h" | #include "opt_ddb.h" | ||||
#if defined(__arm__) | |||||
#include "opt_timer.h" | |||||
#endif | |||||
#include "opt_rss.h" | #include "opt_rss.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/callout.h> | #include <sys/callout.h> | ||||
#include <sys/domainset.h> | #include <sys/domainset.h> | ||||
#include <sys/file.h> | #include <sys/file.h> | ||||
Show All 14 Lines | |||||
#include <ddb/db_sym.h> | #include <ddb/db_sym.h> | ||||
#include <machine/_inttypes.h> | #include <machine/_inttypes.h> | ||||
#endif | #endif | ||||
#ifdef SMP | #ifdef SMP | ||||
#include <machine/cpu.h> | #include <machine/cpu.h> | ||||
#endif | #endif | ||||
#ifndef NO_EVENTTIMERS | |||||
DPCPU_DECLARE(sbintime_t, hardclocktime); | DPCPU_DECLARE(sbintime_t, hardclocktime); | ||||
#endif | |||||
SDT_PROVIDER_DEFINE(callout_execute); | SDT_PROVIDER_DEFINE(callout_execute); | ||||
SDT_PROBE_DEFINE1(callout_execute, , , callout__start, "struct callout *"); | SDT_PROBE_DEFINE1(callout_execute, , , callout__start, "struct callout *"); | ||||
SDT_PROBE_DEFINE1(callout_execute, , , callout__end, "struct callout *"); | SDT_PROBE_DEFINE1(callout_execute, , , callout__end, "struct callout *"); | ||||
#ifdef CALLOUT_PROFILING | #ifdef CALLOUT_PROFILING | ||||
static int avg_depth; | static int avg_depth; | ||||
SYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0, | SYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0, | ||||
▲ Show 20 Lines • Show All 434 Lines • ▼ Show 20 Lines | next: | ||||
firstb++; | firstb++; | ||||
/* | /* | ||||
* Stop if we looked after present time and found | * Stop if we looked after present time and found | ||||
* some event we can't execute at now. | * some event we can't execute at now. | ||||
* Stop if we looked far enough into the future. | * Stop if we looked far enough into the future. | ||||
*/ | */ | ||||
} while (((int)(firstb - lastb)) <= 0); | } while (((int)(firstb - lastb)) <= 0); | ||||
cc->cc_firstevent = last; | cc->cc_firstevent = last; | ||||
#ifndef NO_EVENTTIMERS | |||||
cpu_new_callout(curcpu, last, first); | cpu_new_callout(curcpu, last, first); | ||||
#endif | |||||
#ifdef CALLOUT_PROFILING | #ifdef CALLOUT_PROFILING | ||||
avg_depth_dir += (depth_dir * 1000 - avg_depth_dir) >> 8; | avg_depth_dir += (depth_dir * 1000 - avg_depth_dir) >> 8; | ||||
avg_mpcalls_dir += (mpcalls_dir * 1000 - avg_mpcalls_dir) >> 8; | avg_mpcalls_dir += (mpcalls_dir * 1000 - avg_mpcalls_dir) >> 8; | ||||
avg_lockcalls_dir += (lockcalls_dir * 1000 - avg_lockcalls_dir) >> 8; | avg_lockcalls_dir += (lockcalls_dir * 1000 - avg_lockcalls_dir) >> 8; | ||||
#endif | #endif | ||||
mtx_unlock_spin_flags(&cc->cc_lock, MTX_QUIET); | mtx_unlock_spin_flags(&cc->cc_lock, MTX_QUIET); | ||||
/* | /* | ||||
* swi_sched acquires the thread lock, so we don't want to call it | * swi_sched acquires the thread lock, so we don't want to call it | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | callout_cc_add(struct callout *c, struct callout_cpu *cc, | ||||
c->c_precision = precision; | c->c_precision = precision; | ||||
bucket = callout_get_bucket(c->c_time); | bucket = callout_get_bucket(c->c_time); | ||||
CTR3(KTR_CALLOUT, "precision set for %p: %d.%08x", | CTR3(KTR_CALLOUT, "precision set for %p: %d.%08x", | ||||
c, (int)(c->c_precision >> 32), | c, (int)(c->c_precision >> 32), | ||||
(u_int)(c->c_precision & 0xffffffff)); | (u_int)(c->c_precision & 0xffffffff)); | ||||
LIST_INSERT_HEAD(&cc->cc_callwheel[bucket], c, c_links.le); | LIST_INSERT_HEAD(&cc->cc_callwheel[bucket], c, c_links.le); | ||||
if (cc->cc_bucket == bucket) | if (cc->cc_bucket == bucket) | ||||
cc_exec_next(cc) = c; | cc_exec_next(cc) = c; | ||||
#ifndef NO_EVENTTIMERS | |||||
/* | /* | ||||
* Inform the eventtimers(4) subsystem there's a new callout | * Inform the eventtimers(4) subsystem there's a new callout | ||||
* that has been inserted, but only if really required. | * that has been inserted, but only if really required. | ||||
*/ | */ | ||||
if (SBT_MAX - c->c_time < c->c_precision) | if (SBT_MAX - c->c_time < c->c_precision) | ||||
c->c_precision = SBT_MAX - c->c_time; | c->c_precision = SBT_MAX - c->c_time; | ||||
sbt = c->c_time + c->c_precision; | sbt = c->c_time + c->c_precision; | ||||
if (sbt < cc->cc_firstevent) { | if (sbt < cc->cc_firstevent) { | ||||
cc->cc_firstevent = sbt; | cc->cc_firstevent = sbt; | ||||
cpu_new_callout(cpu, sbt, c->c_time); | cpu_new_callout(cpu, sbt, c->c_time); | ||||
} | } | ||||
#endif | |||||
} | } | ||||
static void | static void | ||||
softclock_call_cc(struct callout *c, struct callout_cpu *cc, | softclock_call_cc(struct callout *c, struct callout_cpu *cc, | ||||
#ifdef CALLOUT_PROFILING | #ifdef CALLOUT_PROFILING | ||||
int *mpcalls, int *lockcalls, int *gcalls, | int *mpcalls, int *lockcalls, int *gcalls, | ||||
#endif | #endif | ||||
int direct) | int direct) | ||||
▲ Show 20 Lines • Show All 228 Lines • ▼ Show 20 Lines | callout_when(sbintime_t sbt, sbintime_t precision, int flags, | ||||
if ((flags & (C_ABSOLUTE | C_PRECALC)) != 0) { | if ((flags & (C_ABSOLUTE | C_PRECALC)) != 0) { | ||||
*res = sbt; | *res = sbt; | ||||
*prec_res = precision; | *prec_res = precision; | ||||
return; | return; | ||||
} | } | ||||
if ((flags & C_HARDCLOCK) != 0 && sbt < tick_sbt) | if ((flags & C_HARDCLOCK) != 0 && sbt < tick_sbt) | ||||
sbt = tick_sbt; | sbt = tick_sbt; | ||||
if ((flags & C_HARDCLOCK) != 0 || | if ((flags & C_HARDCLOCK) != 0 || sbt >= sbt_tickthreshold) { | ||||
#ifdef NO_EVENTTIMERS | |||||
sbt >= sbt_timethreshold) { | |||||
to_sbt = getsbinuptime(); | |||||
/* Add safety belt for the case of hz > 1000. */ | |||||
to_sbt += tc_tick_sbt - tick_sbt; | |||||
#else | |||||
sbt >= sbt_tickthreshold) { | |||||
/* | /* | ||||
* Obtain the time of the last hardclock() call on | * Obtain the time of the last hardclock() call on | ||||
* this CPU directly from the kern_clocksource.c. | * this CPU directly from the kern_clocksource.c. | ||||
* This value is per-CPU, but it is equal for all | * This value is per-CPU, but it is equal for all | ||||
* active ones. | * active ones. | ||||
*/ | */ | ||||
#ifdef __LP64__ | #ifdef __LP64__ | ||||
to_sbt = DPCPU_GET(hardclocktime); | to_sbt = DPCPU_GET(hardclocktime); | ||||
#else | #else | ||||
spinlock_enter(); | spinlock_enter(); | ||||
to_sbt = DPCPU_GET(hardclocktime); | to_sbt = DPCPU_GET(hardclocktime); | ||||
spinlock_exit(); | spinlock_exit(); | ||||
#endif | |||||
#endif | #endif | ||||
if (cold && to_sbt == 0) | if (cold && to_sbt == 0) | ||||
to_sbt = sbinuptime(); | to_sbt = sbinuptime(); | ||||
if ((flags & C_HARDCLOCK) == 0) | if ((flags & C_HARDCLOCK) == 0) | ||||
to_sbt += tick_sbt; | to_sbt += tick_sbt; | ||||
} else | } else | ||||
to_sbt = sbinuptime(); | to_sbt = sbinuptime(); | ||||
if (SBT_MAX - to_sbt < sbt) | if (SBT_MAX - to_sbt < sbt) | ||||
▲ Show 20 Lines • Show All 717 Lines • Show Last 20 Lines |