Daniel A. Steffen | 6 Jul 03:46
Gravatar

Re: after ids


On 05/07/2008, at 19:58, Donal K. Fellows wrote:

> On Darwin[*], times() is documented as returning the number
> of clock ticks since the Unix epoch, and so is inherently coupled to
> absolute time.

the Darwin implementation of times() comes from FreeBSD and is  
completely trivial, the return value is just gettimeofday() in ticks  
(c.f. Darwin source file Libc/gen/times-fbsd.c reproduced below).  
Might be worthwhile checking if current *BSDs still use this technique  
as well...

However, Darwin does have a platform-specific function to get a  
monotonic time reference: mach_absolute_time(), which we are using in  
Tcl already for high-resolution clicks, c.f. TclpGetWideClicks() and  
TclpWideClicksToNanoseconds() in tclUnixTime.c.

mach_absolute_time() is based on the CPU TSC (adjusted for CPU nap/ 
sleep) and is guaranteed to be monotonically increasing, see e.g. the  
following Darwin kernel sources for details:
     xnu/osfmk/i386/rtclock.c
     xnu/osfmk/i386/machine_routines_asm.s
     xnu/osfmk/i386/ommpage/commpage_mach_absolute_time.s
     xnu/osfmk/i386/commpage/commpage.c (commpage_set_nanotime)

All the implementations of relative timers in the OS (nanosleep(),  
pthread_cond_timedwait_relative_np() etc) are based on this reference.

Finding a function that returns an monotonic time reference on a  
system does not solve the problem of implementing relative timers in  
Tcl however, you also need a way for the notifier to wait for a  
relative time interval, e.g. the current threaded unix notifier  
waiting is based on pthread_cond_timedwait(), which uses absolute time  
(c.f. Tcl_ConditionWait()).
Darwin has pthread_cond_timedwait_relative_np() for exactly this  
purpose, I don't know if other systems have something equivalent.

There is also the problem of what to do in the notifier in the  
presence of both absolute and relative timers, i.e. use an absolute or  
a relative timeout? (converting next absolute timer fire to a relative  
time interval may result in waiting for too long if there are changes  
to the gettod base).

Cheers,

Daniel

-- 
** Daniel A. Steffen                   **
** <mailto:das@...>  **


/*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  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.
  * 3. All advertising materials mentioning features or use of this  
software
  *    must display the following acknowledgement:
  *	This product includes software developed by the University of
  *	California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its  
contributors
  *    may be used to endorse or promote products derived from this  
software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
  */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)times.c	8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/gen/times.c,v 1.2 2002/02/01 01:08:48  
obrien Exp $");

#include <sys/param.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/resource.h>

/*
  * Convert usec to clock ticks; could do (usec * CLK_TCK) / 1000000,
  * but this would overflow if we switch to nanosec.
  */
#define	CONVTCK(r)	(r.tv_sec * CLK_TCK + r.tv_usec / (1000000 /  
CLK_TCK))

clock_t
times(tp)
	struct tms *tp;
{
	struct rusage ru;
	struct timeval t;

	if (getrusage(RUSAGE_SELF, &ru) < 0)
		return ((clock_t)-1);
	tp->tms_utime = CONVTCK(ru.ru_utime);
	tp->tms_stime = CONVTCK(ru.ru_stime);
	if (getrusage(RUSAGE_CHILDREN, &ru) < 0)
		return ((clock_t)-1);
	tp->tms_cutime = CONVTCK(ru.ru_utime);
	tp->tms_cstime = CONVTCK(ru.ru_stime);
	if (gettimeofday(&t, (struct timezone *)0))
		return ((clock_t)-1);
	return ((clock_t)(CONVTCK(t)));
}

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08

Gmane