summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2011-05-16 15:29:59 +0000
committeravg <avg@FreeBSD.org>2011-05-16 15:29:59 +0000
commit576b51ab8f786d77da023fb2e83fdc1fb0c7abf6 (patch)
treeb2c4b470c3bfa995c74975f76d90d27867ff83a4 /sys/cddl
parent90fe5b5b3e46a2da849cf8d0bba00f4834d39398 (diff)
downloadFreeBSD-src-576b51ab8f786d77da023fb2e83fdc1fb0c7abf6.zip
FreeBSD-src-576b51ab8f786d77da023fb2e83fdc1fb0c7abf6.tar.gz
better integrate cyclic module with clocksource/eventtimer subsystem
Now in the case when one-shot timers are used cyclic events should fire closer to theier scheduled times. As the cyclic is currently used only to drive DTrace profile provider, this is the area where the change makes a difference. Reviewed by: mav (earlier version, a while ago) X-MFC after: clocksource/eventtimer subsystem
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/compat/opensolaris/sys/time.h2
-rw-r--r--sys/cddl/dev/cyclic/cyclic.c14
-rw-r--r--sys/cddl/dev/cyclic/i386/cyclic_machdep.c40
3 files changed, 34 insertions, 22 deletions
diff --git a/sys/cddl/compat/opensolaris/sys/time.h b/sys/cddl/compat/opensolaris/sys/time.h
index 05db50e..cd5e695 100644
--- a/sys/cddl/compat/opensolaris/sys/time.h
+++ b/sys/cddl/compat/opensolaris/sys/time.h
@@ -53,7 +53,7 @@ gethrtime(void) {
struct timespec ts;
hrtime_t nsec;
- getnanouptime(&ts);
+ nanouptime(&ts);
nsec = (hrtime_t)ts.tv_sec * NANOSEC + ts.tv_nsec;
return (nsec);
}
diff --git a/sys/cddl/dev/cyclic/cyclic.c b/sys/cddl/dev/cyclic/cyclic.c
index b9a6979..e7b7f50 100644
--- a/sys/cddl/dev/cyclic/cyclic.c
+++ b/sys/cddl/dev/cyclic/cyclic.c
@@ -341,6 +341,16 @@ static cyc_backend_t cyclic_backend;
MALLOC_DEFINE(M_CYCLIC, "cyclic", "Cyclic timer subsystem");
+static __inline hrtime_t
+cyc_gethrtime(void)
+{
+ struct bintime bt;
+
+ binuptime(&bt);
+ return ((hrtime_t)bt.sec * NANOSEC +
+ (((uint64_t)NANOSEC * (uint32_t)(bt.frac >> 32)) >> 32));
+}
+
/*
* Returns 1 if the upheap propagated to the root, 0 if it did not. This
* allows the caller to reprogram the backend only when the root has been
@@ -507,7 +517,7 @@ cyclic_fire(cpu_t *c)
cyc_index_t *heap = cpu->cyp_heap;
cyclic_t *cyclic, *cyclics = cpu->cyp_cyclics;
void *arg = be->cyb_arg;
- hrtime_t now = gethrtime();
+ hrtime_t now = cyc_gethrtime();
hrtime_t exp;
if (cpu->cyp_nelems == 0) {
@@ -687,7 +697,7 @@ cyclic_add_xcall(cyc_xcallarg_t *arg)
* If a start time hasn't been explicitly specified, we'll
* start on the next interval boundary.
*/
- cyclic->cy_expire = (gethrtime() / cyclic->cy_interval + 1) *
+ cyclic->cy_expire = (cyc_gethrtime() / cyclic->cy_interval + 1) *
cyclic->cy_interval;
} else {
cyclic->cy_expire = when->cyt_when;
diff --git a/sys/cddl/dev/cyclic/i386/cyclic_machdep.c b/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
index 1c18fc1..6f93663 100644
--- a/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
+++ b/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
@@ -30,6 +30,7 @@ static void enable(cyb_arg_t);
static void disable(cyb_arg_t);
static void reprogram(cyb_arg_t, hrtime_t);
static void xcall(cyb_arg_t, cpu_t *, cyc_func_t, void *);
+static void cyclic_clock(struct trapframe *frame);
static cyc_backend_t be = {
NULL, /* cyb_configure */
@@ -45,6 +46,7 @@ static void
cyclic_ap_start(void *dummy)
{
/* Initialise the rest of the CPUs. */
+ cyclic_clock_func = cyclic_clock;
cyclic_mp_init();
}
@@ -63,18 +65,10 @@ cyclic_machdep_init(void)
static void
cyclic_machdep_uninit(void)
{
- int i;
-
- for (i = 0; i <= mp_maxid; i++)
- /* Reset the cyclic clock callback hook. */
- cyclic_clock_func[i] = NULL;
-
/* De-register the cyclic backend. */
cyclic_uninit();
}
-static hrtime_t exp_due[MAXCPU];
-
/*
* This function is the one registered by the machine dependent
* initialiser as the callback for high speed timer events.
@@ -84,7 +78,7 @@ cyclic_clock(struct trapframe *frame)
{
cpu_t *c = &solaris_cpu[curcpu];
- if (c->cpu_cyclic != NULL && gethrtime() >= exp_due[curcpu]) {
+ if (c->cpu_cyclic != NULL) {
if (TRAPF_USERMODE(frame)) {
c->cpu_profile_pc = 0;
c->cpu_profile_upc = TRAPF_PC(frame);
@@ -102,26 +96,34 @@ cyclic_clock(struct trapframe *frame)
}
}
-static void enable(cyb_arg_t arg)
+static void
+enable(cyb_arg_t arg __unused)
{
- /* Register the cyclic clock callback function. */
- cyclic_clock_func[curcpu] = cyclic_clock;
+
}
-static void disable(cyb_arg_t arg)
+static void
+disable(cyb_arg_t arg __unused)
{
- /* Reset the cyclic clock callback function. */
- cyclic_clock_func[curcpu] = NULL;
+
}
-static void reprogram(cyb_arg_t arg, hrtime_t exp)
+static void
+reprogram(cyb_arg_t arg __unused, hrtime_t exp)
{
- exp_due[curcpu] = exp;
+ struct bintime bt;
+ struct timespec ts;
+
+ ts.tv_sec = exp / 1000000000;
+ ts.tv_nsec = exp % 1000000000;
+ timespec2bintime(&ts, &bt);
+ clocksource_cyc_set(&bt);
}
-static void xcall(cyb_arg_t arg, cpu_t *c, cyc_func_t func, void *param)
+static void xcall(cyb_arg_t arg __unused, cpu_t *c, cyc_func_t func,
+ void *param)
{
- smp_rendezvous_cpus((cpumask_t) (1 << c->cpuid),
+ smp_rendezvous_cpus((cpumask_t)1 << c->cpuid,
smp_no_rendevous_barrier, func, smp_no_rendevous_barrier, param);
}
OpenPOWER on IntegriCloud