On Sun, 27 Nov 2005, Robert Watson wrote:
Add experimental low-precision clockid_t names corresponding to these
clocks, but implemented using cached timestamps in kernel rather than
a full time counter query. This offers a minimum update rate of 1/HZ,
but in practice will often be more frequent due to the frequency of
time stamping in the kernel:
New clockid_t name Approximates existing clockid_t
CLOCK_REALTIME_FAST CLOCK_REALTIME
CLOCK_MONOTONIC_FAST CLOCK_MONOTONIC
CLOCK_UPTIME_FAST CLOCK_UPTIME
Add one additional new clockid_t, CLOCK_SECOND, which returns the
current second without performing a full time counter query or cache
lookup overhead to make sure the cached timestamp is stable. This is
intended to support very low granularity consumers, such as time(3).
These changes are primarily intended to support the identification of
time-associated bottlenecks and allow experimentation with application
scoped reduction in quality of time use. Attached is a small LD_PRELOAD
library to allow applications to be switched to the _FAST variants for
gettimeofday(). Build and install, then set:
LD_PRELOAD=/usr/lib/libwrapper.so ; export LD_PRELOAD
This is not intended to be the last word in how this should be done --
more, to facilitate some experimentation by providing some framework for
experimentation (i.e., a sample API and code to tweak applications). I
expect that the details will be subject to substantial change. :-)
Robert N M Watson
# $FreeBSD$
LIB= wrapper
SHLIB_MAJOR= 1
SRCS= wrapper.c
NO_MAN=
.include <bsd.lib.mk>
/*-
* Copyright (c) 2005 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* Small wrapper library to substitute implementations of gettimeofday(2) and
* time(3) with lower resolution variations. time(3) is unconditionally
* degraded, since it will return a truncated time anyway. gettimeofday(3)
* checks the TIMEWRAPPER environmental variable, which can be set to either
* "PRECISE" or "FAST".
*/
#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
static int timewrapper_initialized;
static clockid_t timewrapper_clock;
/*
* Select whatever system default is present for CLOCK_REALTIME as the
* default if the environmental variable is unset, or set to an invalid
* value.
*/
#define TIMEWRAPPER_ENV "TIMEWRAPPER"
#define TIMEWRAPPER_DEFAULT CLOCK_REALTIME
#define TIMEWRAPPER_STRPRECISE "PRECISE"
#define TIMEWRAPPER_STRFAST "FAST"
static void
timewrapper_initialize(void)
{
const char *whichclock_env;
whichclock_env = getenv(TIMEWRAPPER_ENV);
if (whichclock_env == NULL) {
timewrapper_clock = TIMEWRAPPER_DEFAULT;
timewrapper_initialized = 1;
return;
}
if (strcmp(whichclock_env, TIMEWRAPPER_STRPRECISE) == 0)
timewrapper_clock = CLOCK_REALTIME_PRECISE;
else if (strcmp(whichclock_env, TIMEWRAPPER_STRFAST) == 0)
timewrapper_clock = CLOCK_REALTIME_FAST;
else
timewrapper_clock = TIMEWRAPPER_DEFAULT;
timewrapper_initialized = 1;
}
int
gettimeofday(struct timeval *tp, struct timezone *tzp)
{
struct timespec ts;
if (!timewrapper_initialized)
timewrapper_initialize();
/*
* XXXRW: Not ideal, since returning EINVAL from gettimeofday() isn't
* expected. Fall back to the gettimeofday() system call instead?
*/
if (clock_gettime(timewrapper_clock, &ts) < 0)
return (-1);
tp->tv_sec = ts.tv_sec;
tp->tv_usec = ts.tv_nsec / 1000;
return (0);
}
time_t
time(time_t *tloc)
{
struct timespec ts;
if (clock_gettime(CLOCK_SECOND, &ts) < 0) {
if (tloc != NULL)
*tloc = -1;
return (-1);
}
if (tloc != NULL)
*tloc = ts.tv_sec;
return (ts.tv_sec);
}
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/cvs-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"