Bug 757593: Make PR_IntervalNow monotonic for Android, Linux, Mac OS X, and

iOS. r=bsmith.
Modified Files:
	_aix.h _bsdi.h _darwin.h _dgux.h _freebsd.h _hpux.h _linux.h
	_netbsd.h _nto.h _openbsd.h _osf1.h _qnx.h _riscos.h _scoos.h
	_symbian.h _unixos.h _unixware.h pr/src/Makefile.in darwin.c
	unix.c prinrval.c


git-svn-id: svn://10.0.0.236/trunk@264379 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
wtc%google.com 2012-10-24 22:33:36 +00:00
parent a0aef40235
commit e8398a797e
21 changed files with 100 additions and 51 deletions

View File

@ -55,6 +55,8 @@
/* Timer operations */
#if defined(AIX_TIMERS)
#define _MD_INTERVAL_INIT()
extern PRIntervalTime _MD_AixGetInterval(void);
#define _MD_GET_INTERVAL _MD_AixGetInterval
@ -62,8 +64,7 @@ extern PRIntervalTime _MD_AixIntervalPerSec(void);
#define _MD_INTERVAL_PER_SEC _MD_AixIntervalPerSec
#else /* defined(AIX_TIMERS) */
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#endif /* defined(AIX_TIMERS) */
#ifdef AIX_HAVE_ATOMIC_OP_H

View File

@ -176,7 +176,6 @@ struct _MDCPU {
#include <sys/syscall.h>
#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#endif /* nspr_bsdi_defs_h___ */

View File

@ -280,12 +280,14 @@ extern void _MD_YIELD(void);
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_INIT _PR_Mach_IntervalInit
#define _MD_GET_INTERVAL _PR_Mach_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_Mach_TicksPerSecond
extern void _MD_EarlyInit(void);
extern PRIntervalTime _PR_UNIX_GetInterval(void);
extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
extern void _PR_Mach_IntervalInit(void);
extern PRIntervalTime _PR_Mach_GetInterval(void);
extern PRIntervalTime _PR_Mach_TicksPerSecond(void);
/*
* We wrapped the select() call. _MD_SELECT refers to the built-in,

View File

@ -158,8 +158,7 @@ struct _MDCPU {
* some of them should probably be moved into _unixos.h. But
* _irix.h seems to be quite different in regard to these macros.
*/
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit

View File

@ -215,13 +215,10 @@ extern void _MD_YIELD(void);
#endif /* ! _PR_PTHREADS */
extern void _MD_EarlyInit(void);
extern PRIntervalTime _PR_UNIX_GetInterval(void);
extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
/*
* We wrapped the select() call. _MD_SELECT refers to the built-in,

View File

@ -269,8 +269,7 @@ extern PRIntervalTime _PR_HPUX_LW_GetInterval(void);
#define _MD_GET_INTERVAL _PR_HPUX_LW_GetInterval
#define _MD_INTERVAL_PER_SEC() 1000
#else
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#endif
/*

View File

@ -626,13 +626,10 @@ extern void _MD_YIELD(void);
#endif /* ! _PR_PTHREADS */
extern void _MD_EarlyInit(void);
extern PRIntervalTime _PR_UNIX_GetInterval(void);
extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define HAVE_MONOTONIC_CLOCK
/*
* We wrapped the select() call. _MD_SELECT refers to the built-in,

View File

@ -208,13 +208,10 @@ struct _MDCPU {
#endif /* ! _PR_PTHREADS */
extern void _MD_EarlyInit(void);
extern PRIntervalTime _PR_UNIX_GetInterval(void);
extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
/*
* We wrapped the select() call. _MD_SELECT refers to the built-in,

View File

@ -167,8 +167,7 @@ struct _MDCPU {
#define _MD_IOQ_LOCK()
#define _MD_IOQ_UNLOCK()
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)

View File

@ -192,8 +192,7 @@ struct _MDCPU {
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
/*
* We wrapped the select() call. _MD_SELECT refers to the built-in,

View File

@ -186,8 +186,7 @@ struct _MDCPU {
* some of them should probably be moved into _unixos.h. But
* _irix.h seems to be quite different in regard to these macros.
*/
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit

View File

@ -158,8 +158,7 @@ struct _MDCPU {
#define _MD_IOQ_LOCK()
#define _MD_IOQ_UNLOCK()
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)

View File

@ -154,8 +154,7 @@ struct _MDCPU {
#define _MD_IOQ_LOCK()
#define _MD_IOQ_UNLOCK()
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)

View File

@ -163,8 +163,7 @@ struct _MDCPU {
#define _MD_RESUME_THREAD(thread)
#define _MD_CLEAN_THREAD(_thread)
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#define _MD_SELECT _select
#define _MD_POLL _poll

View File

@ -39,13 +39,10 @@
#endif
extern void _MD_EarlyInit(void);
extern PRIntervalTime _PR_UNIX_GetInterval(void);
extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
/* For writev() */
#include <sys/uio.h>

View File

@ -294,9 +294,22 @@ extern void _MD_FreeSegment(PRSegment *seg);
/************************************************************************/
#if !defined(HPUX_LW_TIMER)
#ifdef _MD_INTERVAL_USE_GTOD
extern PRIntervalTime _PR_UNIX_GetInterval(void);
extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
#define _MD_INTERVAL_INIT()
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#endif
#ifdef HAVE_MONOTONIC_CLOCK
extern PRIntervalTime _PR_UNIX_GetInterval2(void);
extern PRIntervalTime _PR_UNIX_TicksPerSecond2(void);
#define _MD_INTERVAL_INIT()
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval2
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond2
#endif
#define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000)
#define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000)

View File

@ -158,8 +158,7 @@ struct _MDCPU {
* some of them should probably be moved into _unixos.h. But
* _irix.h seems to be quite different in regard to these macros.
*/
#define _MD_GET_INTERVAL _PR_UNIX_GetInterval
#define _MD_INTERVAL_PER_SEC _PR_UNIX_TicksPerSecond
#define _MD_INTERVAL_USE_GTOD
#define _MD_EARLY_INIT _MD_EarlyInit
#define _MD_FINAL_INIT _PR_UnixInit

View File

@ -133,6 +133,7 @@ endif
else
OS_LIBS = -ldl
endif
OS_LIBS += -lrt
endif
ifeq ($(OS_ARCH),HP-UX)

View File

@ -5,10 +5,41 @@
#include "primpl.h"
#include <mach/mach_time.h>
void _MD_EarlyInit(void)
{
}
static mach_timebase_info_data_t machTimebaseInfo;
void _PR_Mach_IntervalInit(void)
{
kern_return_t rv;
rv = mach_timebase_info(&machTimebaseInfo);
PR_ASSERT(rv == KERN_SUCCESS);
}
PRIntervalTime _PR_Mach_GetInterval(void)
{
uint64_t time;
/*
* mach_absolute_time returns the number of nanoseconds since boot.
* Convert it to the number of 10-microseconds. See Mac Technical Q&A
* QA1398.
*/
time = mach_absolute_time();
time = time / 10000 * machTimebaseInfo.numer / machTimebaseInfo.denom;
return (PRIntervalTime)time;
} /* _PR_Mach_GetInterval */
PRIntervalTime _PR_Mach_TicksPerSecond(void)
{
return 100000;
}
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
{
#if !defined(_PR_PTHREADS)

View File

@ -3017,6 +3017,13 @@ PR_Now(void)
return s;
}
#if defined(_MD_INTERVAL_USE_GTOD)
/*
* This version of interval times is based on the time of day
* capability offered by the system. This isn't valid for two reasons:
* 1) The time of day is neither linear nor montonically increasing
* 2) The units here are milliseconds. That's not appropriate for our use.
*/
PRIntervalTime _PR_UNIX_GetInterval()
{
struct timeval time;
@ -3026,12 +3033,35 @@ PRIntervalTime _PR_UNIX_GetInterval()
ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; /* that's in milliseconds */
ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC; /* so's that */
return ticks;
} /* _PR_SUNOS_GetInterval */
} /* _PR_UNIX_GetInterval */
PRIntervalTime _PR_UNIX_TicksPerSecond()
{
return 1000; /* this needs some work :) */
}
#endif
#if defined(HAVE_MONOTONIC_CLOCK)
PRIntervalTime _PR_UNIX_GetInterval2()
{
struct timespec time;
PRIntervalTime ticks;
if (clock_gettime(CLOCK_MONOTONIC, &time) != 0) {
fprintf(stderr, "clock_gettime failed: %d\n", errno);
abort();
}
ticks = (PRUint32)time.tv_sec * 100000;
ticks += (PRUint32)time.tv_nsec / 10000;
return ticks;
}
PRIntervalTime _PR_UNIX_TicksPerSecond2()
{
return 100000;
}
#endif
#if !defined(_PR_PTHREADS)
/*

View File

@ -32,13 +32,6 @@ void _PR_InitClock(void)
#endif /* DEBUG */
}
/*
* This version of interval times is based on the time of day
* capability offered by system. This isn't valid for two reasons:
* 1) The time of day is neither linear nor montonically increasing
* 2) The units here are milliseconds. That's not appropriate for our use.
*/
PR_IMPLEMENT(PRIntervalTime) PR_IntervalNow(void)
{
if (!_pr_initialized) _PR_ImplicitInitialization();