Date: Fri, 29 Jun 2012 16:06:06 +0000 (UTC) From: Davide Italiano <davide@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r237796 - in projects/calloutng/sys: kern sys Message-ID: <201206291606.q5TG66nq055462@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: davide Date: Fri Jun 29 16:06:06 2012 New Revision: 237796 URL: http://svn.freebsd.org/changeset/base/237796 Log: Experiment a new approach used for low-precision events, try to align them to some time borders on insert. This approach can make system load more bursty, but it is very cheap to be implemented and may be quite effective. Moreover, it can easily coexist with the previously implemented "real-time aggregation". Discussed with: mav Modified: projects/calloutng/sys/kern/kern_timeout.c projects/calloutng/sys/sys/callout.h Modified: projects/calloutng/sys/kern/kern_timeout.c ============================================================================== --- projects/calloutng/sys/kern/kern_timeout.c Fri Jun 29 15:57:25 2012 (r237795) +++ projects/calloutng/sys/kern/kern_timeout.c Fri Jun 29 16:06:06 2012 (r237796) @@ -497,8 +497,7 @@ callout_cc_add(struct callout *c, struct struct bintime to_bintime, void (*func)(void *), void *arg, int cpu, int flags) { - struct timeval tv; - int bucket; + int bucket, r_shift, r_val; CC_LOCK_ASSERT(cc); if (bintime_cmp(&to_bintime, &cc->cc_lastscan, <)) { @@ -510,25 +509,38 @@ callout_cc_add(struct callout *c, struct c->c_flags |= CALLOUT_DIRECT; c->c_flags &= ~CALLOUT_PROCESSED; c->c_func = func; - c->c_time = to_bintime; - tv.tv_sec = 0; - if (flags & C_10US) { - tv.tv_usec = 10; - timeval2bintime(&tv, &c->c_precision); - } - else if (flags & C_100US) { - tv.tv_usec = 100; - timeval2bintime(&tv, &c->c_precision); - } - else if (flags & C_1MS) { - tv.tv_usec = 1000; - timeval2bintime(&tv, &c->c_precision); + c->c_time = to_bintime; + bintime_clear(&c->c_precision); + if (flags & 0x2) { + r_shift = ((flags >> 2) & PRECISION_RANGE); + r_val = (r_shift != 0) ? (uint64_t)1 << (64 - r_shift) : 0; + /* + * Round as far as precision specified is coarse (up to 8ms). + * In order to play safe, round to to half of the interval and + * set half precision. + */ + if (r_shift < 6) { + r_val = (r_shift != 0) ? r_val >> 2 : + ((uint64_t)1 << (64 - 1)) - 1; + /* + * Round only if c_time is not a multiple of the + * rounding factor. + */ + if ((c->c_time.frac & r_val) != r_val) { + c->c_time.frac |= r_val - 1; + c->c_time.frac += 1; + if (c->c_time.frac == 0) + c->c_time.sec += 1; + } + } + c->c_precision.frac = r_val; + CTR6(KTR_CALLOUT, "rounding %d.%u%u to %d.%u%u", + to_bintime.sec, (u_int) (to_bintime.frac >> 32), + (u_int) (to_bintime.frac & 0xffffffff), c->c_time.sec, + (u_int) (c->c_time.frac >> 32), + (u_int) (c->c_time.frac & 0xffffffff)); } - else { - c->c_precision.sec = 0; - c->c_precision.frac = 0; - } - bucket = get_bucket(&c->c_time); + bucket = get_bucket(&c->c_time); TAILQ_INSERT_TAIL(&cc->cc_callwheel[bucket & callwheelmask], c, c_links.tqe); /* @@ -536,10 +548,10 @@ callout_cc_add(struct callout *c, struct * that has been inserted. */ if (callout_new_inserted != NULL && - (bintime_cmp(&to_bintime, &cc->cc_firstevent, <) || + (bintime_cmp(&c->c_time, &cc->cc_firstevent, <) || (cc->cc_firstevent.sec == 0 && cc->cc_firstevent.frac == 0))) { - cc->cc_firstevent = to_bintime; - (*callout_new_inserted)(cpu, to_bintime); + cc->cc_firstevent = c->c_time; + (*callout_new_inserted)(cpu, c->c_time); } } Modified: projects/calloutng/sys/sys/callout.h ============================================================================== --- projects/calloutng/sys/sys/callout.h Fri Jun 29 15:57:25 2012 (r237795) +++ projects/calloutng/sys/sys/callout.h Fri Jun 29 16:06:06 2012 (r237796) @@ -51,9 +51,28 @@ #define CALLOUT_DIRECT 0x1000 /* allow exec from hw int context */ #define C_DIRECT_EXEC 0x0001 /* direct execution of callout */ -#define C_10US 0x0002 /* precision field */ -#define C_100US 0x0004 /* precision field */ -#define C_1MS 0x0008 /* precision field */ +#define C_P1S 0x0002 /* fields related to precision */ +#define C_P500MS 0x0006 +#define C_P250MS 0x000a +#define C_P125MS 0x000e +#define C_P64MS 0x0012 +#define C_P32MS 0x0016 +#define C_P16MS 0x001a +#define C_P8MS 0x001e +#define C_P4MS 0x0022 +#define C_P2MS 0x0026 +#define C_P1MS 0x002a +#define C_P500US 0x002e +#define C_P250US 0x0032 +#define C_P125US 0x0036 +#define C_P64US 0x003a +#define C_P32US 0x003e +#define C_P16US 0x0042 +#define C_P8US 0x0046 +#define C_P4US 0x004a +#define C_P2US 0x004e +#define PRECISION_BITS 7 +#define PRECISION_RANGE ((1 << PRECISION_BITS) - 1) struct callout_handle { struct callout *callout;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206291606.q5TG66nq055462>