зеркало из https://github.com/mozilla/pjs.git
Bug 491441: Update NSPR to the NSPR_HEAD_20090505 CVS tag.
Bug 491441: Firefox crashes on startup in PR_SetLogFile() with NSPR_LOG_FILE env var set Bug 488621: PR_Now() resolution on Windows Mobile is 1 second. Moving tag to fix regression from Bug 432430 [PATCH] NSPR port to Symbian OS, unit tests tested
This commit is contained in:
Родитель
520dbc7d37
Коммит
00db2778c1
|
@ -54,17 +54,19 @@
|
|||
#include <kernel/OS.h>
|
||||
#endif
|
||||
|
||||
#ifdef WINNT
|
||||
/* Need to force service-pack 3 extensions to be defined by
|
||||
** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h.
|
||||
*/
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#elif (_WIN32_WINNT < 0x0400)
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif /* _WIN32_WINNT */
|
||||
#endif /* WINNT */
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* Allow use of functions and symbols first defined in Win2k.
|
||||
*/
|
||||
#if !defined(WINVER) || (WINVER < 0x0500)
|
||||
#undef WINVER
|
||||
#define WINVER 0x0500
|
||||
#endif
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#endif
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include "nspr.h"
|
||||
#include "prpriv.h"
|
||||
|
@ -1215,6 +1217,13 @@ extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock,
|
|||
|
||||
extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls);
|
||||
#define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT
|
||||
/*
|
||||
* The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
|
||||
* We store the value in a PRTime variable for convenience.
|
||||
* This constant is used by _PR_FileTimeToPRTime().
|
||||
* This is defined in ntmisc.c
|
||||
*/
|
||||
extern const PRTime _pr_filetime_offset;
|
||||
#endif /* WIN32 */
|
||||
|
||||
extern PRInt32 _PR_MD_SENDFILE(
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
#define _PRSockLen_t int
|
||||
#elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
|
||||
|| defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \
|
||||
|| defined(DGUX) || defined(VMS) || defined(NTO) || defined(RISCOS)
|
||||
|| defined(DGUX) || defined(NTO) || defined(RISCOS)
|
||||
#define _PRSockLen_t size_t
|
||||
#else
|
||||
#error "Cannot determine architecture"
|
||||
|
@ -2649,7 +2649,11 @@ PRInt32 _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info)
|
|||
return rv;
|
||||
}
|
||||
|
||||
#ifdef SYMBIAN
|
||||
struct _MD_IOVector _md_iovector;
|
||||
#else
|
||||
struct _MD_IOVector _md_iovector = { open };
|
||||
#endif
|
||||
|
||||
/*
|
||||
** These implementations are to emulate large file routines on systems that
|
||||
|
|
|
@ -100,17 +100,6 @@ static DWORD dirAccessTable[] = {
|
|||
FILE_GENERIC_EXECUTE
|
||||
};
|
||||
|
||||
/*
|
||||
* The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
|
||||
* We store the value in a PRTime variable for convenience.
|
||||
* This constant is used by _PR_FileTimeToPRTime().
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
static const PRTime _pr_filetime_offset = 116444736000000000LL;
|
||||
#else
|
||||
static const PRTime _pr_filetime_offset = 116444736000000000i64;
|
||||
#endif
|
||||
|
||||
static PRBool IsPrevCharSlash(const char *str, const char *current);
|
||||
|
||||
#define _NEED_351_FILE_LOCKING_HACK
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
*/
|
||||
|
||||
#include "primpl.h"
|
||||
#include <math.h> /* for fabs() */
|
||||
#include <windows.h>
|
||||
|
||||
char *_PR_MD_GET_ENV(const char *name)
|
||||
{
|
||||
|
@ -68,6 +70,116 @@ PRIntn _PR_MD_PUT_ENV(const char *name)
|
|||
**************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
|
||||
* We store the value in a PRTime variable for convenience.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
const PRTime _pr_filetime_offset = 116444736000000000LL;
|
||||
#else
|
||||
const PRTime _pr_filetime_offset = 116444736000000000i64;
|
||||
#endif
|
||||
|
||||
#ifdef WINCE
|
||||
|
||||
#define FILETIME2INT64(ft) \
|
||||
(((PRInt64)ft.dwHighDateTime) << 32 | (PRInt64)ft.dwLowDateTime)
|
||||
|
||||
static void
|
||||
LowResTime(LPFILETIME lpft)
|
||||
{
|
||||
GetCurrentFT(lpft);
|
||||
}
|
||||
|
||||
typedef struct CalibrationData {
|
||||
long double freq; /* The performance counter frequency */
|
||||
long double offset; /* The low res 'epoch' */
|
||||
long double timer_offset; /* The high res 'epoch' */
|
||||
|
||||
/* The last high res time that we returned since recalibrating */
|
||||
PRInt64 last;
|
||||
|
||||
PRBool calibrated;
|
||||
|
||||
CRITICAL_SECTION data_lock;
|
||||
CRITICAL_SECTION calibration_lock;
|
||||
PRInt64 granularity;
|
||||
} CalibrationData;
|
||||
|
||||
static CalibrationData calibration;
|
||||
|
||||
static void
|
||||
NowCalibrate(void)
|
||||
{
|
||||
FILETIME ft, ftStart;
|
||||
LARGE_INTEGER liFreq, now;
|
||||
|
||||
if (calibration.freq == 0.0) {
|
||||
if(!QueryPerformanceFrequency(&liFreq)) {
|
||||
/* High-performance timer is unavailable */
|
||||
calibration.freq = -1.0;
|
||||
} else {
|
||||
calibration.freq = (long double) liFreq.QuadPart;
|
||||
}
|
||||
}
|
||||
if (calibration.freq > 0.0) {
|
||||
PRInt64 calibrationDelta = 0;
|
||||
/*
|
||||
* By wrapping a timeBegin/EndPeriod pair of calls around this loop,
|
||||
* the loop seems to take much less time (1 ms vs 15ms) on Vista.
|
||||
*/
|
||||
timeBeginPeriod(1);
|
||||
LowResTime(&ftStart);
|
||||
do {
|
||||
LowResTime(&ft);
|
||||
} while (memcmp(&ftStart,&ft, sizeof(ft)) == 0);
|
||||
timeEndPeriod(1);
|
||||
|
||||
calibration.granularity =
|
||||
(FILETIME2INT64(ft) - FILETIME2INT64(ftStart))/10;
|
||||
|
||||
QueryPerformanceCounter(&now);
|
||||
|
||||
calibration.offset = (long double) FILETIME2INT64(ft);
|
||||
calibration.timer_offset = (long double) now.QuadPart;
|
||||
/*
|
||||
* The windows epoch is around 1600. The unix epoch is around 1970.
|
||||
* _pr_filetime_offset is the difference (in windows time units which
|
||||
* are 10 times more highres than the JS time unit)
|
||||
*/
|
||||
calibration.offset -= _pr_filetime_offset;
|
||||
calibration.offset *= 0.1;
|
||||
calibration.last = 0;
|
||||
|
||||
calibration.calibrated = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#define CALIBRATIONLOCK_SPINCOUNT 0
|
||||
#define DATALOCK_SPINCOUNT 4096
|
||||
#define LASTLOCK_SPINCOUNT 4096
|
||||
|
||||
static PRStatus
|
||||
_MD_InitTime(void)
|
||||
{
|
||||
memset(&calibration, 0, sizeof(calibration));
|
||||
NowCalibrate();
|
||||
InitializeCriticalSection(&calibration.calibration_lock);
|
||||
InitializeCriticalSection(&calibration.data_lock);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_MD_CleanupTime(void)
|
||||
{
|
||||
DeleteCriticalSection(&calibration.calibration_lock);
|
||||
DeleteCriticalSection(&calibration.data_lock);
|
||||
}
|
||||
|
||||
#define MUTEX_SETSPINCOUNT(m, c)
|
||||
|
||||
static PRCallOnceType calibrationOnce;
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------
|
||||
*
|
||||
|
@ -82,6 +194,130 @@ PRIntn _PR_MD_PUT_ENV(const char *name)
|
|||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
PR_IMPLEMENT(PRTime)
|
||||
PR_Now(void)
|
||||
{
|
||||
long double lowresTime, highresTimerValue;
|
||||
FILETIME ft;
|
||||
LARGE_INTEGER now;
|
||||
PRBool calibrated = PR_FALSE;
|
||||
PRBool needsCalibration = PR_FALSE;
|
||||
PRInt64 returnedTime;
|
||||
long double cachedOffset = 0.0;
|
||||
|
||||
/* For non threadsafe platforms, _MD_InitTime is not necessary */
|
||||
PR_CallOnce(&calibrationOnce, _MD_InitTime);
|
||||
do {
|
||||
if (!calibration.calibrated || needsCalibration) {
|
||||
EnterCriticalSection(&calibration.calibration_lock);
|
||||
EnterCriticalSection(&calibration.data_lock);
|
||||
|
||||
/* Recalibrate only if no one else did before us */
|
||||
if (calibration.offset == cachedOffset) {
|
||||
/*
|
||||
* Since calibration can take a while, make any other
|
||||
* threads immediately wait
|
||||
*/
|
||||
MUTEX_SETSPINCOUNT(&calibration.data_lock, 0);
|
||||
|
||||
NowCalibrate();
|
||||
|
||||
calibrated = PR_TRUE;
|
||||
|
||||
/* Restore spin count */
|
||||
MUTEX_SETSPINCOUNT(&calibration.data_lock, DATALOCK_SPINCOUNT);
|
||||
}
|
||||
LeaveCriticalSection(&calibration.data_lock);
|
||||
LeaveCriticalSection(&calibration.calibration_lock);
|
||||
}
|
||||
|
||||
/* Calculate a low resolution time */
|
||||
LowResTime(&ft);
|
||||
lowresTime = ((long double)(FILETIME2INT64(ft) - _pr_filetime_offset))
|
||||
* 0.1;
|
||||
|
||||
if (calibration.freq > 0.0) {
|
||||
long double highresTime, diff;
|
||||
DWORD timeAdjustment, timeIncrement;
|
||||
BOOL timeAdjustmentDisabled;
|
||||
|
||||
/* Default to 15.625 ms if the syscall fails */
|
||||
long double skewThreshold = 15625.25;
|
||||
|
||||
/* Grab high resolution time */
|
||||
QueryPerformanceCounter(&now);
|
||||
highresTimerValue = (long double)now.QuadPart;
|
||||
|
||||
EnterCriticalSection(&calibration.data_lock);
|
||||
highresTime = calibration.offset + 1000000L *
|
||||
(highresTimerValue-calibration.timer_offset)/calibration.freq;
|
||||
cachedOffset = calibration.offset;
|
||||
|
||||
/*
|
||||
* On some dual processor/core systems, we might get an earlier
|
||||
* time so we cache the last time that we returned.
|
||||
*/
|
||||
calibration.last = PR_MAX(calibration.last,(PRInt64)highresTime);
|
||||
returnedTime = calibration.last;
|
||||
LeaveCriticalSection(&calibration.data_lock);
|
||||
|
||||
/* Get an estimate of clock ticks per second from our own test */
|
||||
skewThreshold = calibration.granularity;
|
||||
/* Check for clock skew */
|
||||
diff = lowresTime - highresTime;
|
||||
|
||||
/*
|
||||
* For some reason that I have not determined, the skew can be
|
||||
* up to twice a kernel tick. This does not seem to happen by
|
||||
* itself, but I have only seen it triggered by another program
|
||||
* doing some kind of file I/O. The symptoms are a negative diff
|
||||
* followed by an equally large positive diff.
|
||||
*/
|
||||
if (fabs(diff) > 2*skewThreshold) {
|
||||
if (calibrated) {
|
||||
/*
|
||||
* If we already calibrated once this instance, and the
|
||||
* clock is still skewed, then either the processor(s) are
|
||||
* wildly changing clockspeed or the system is so busy that
|
||||
* we get switched out for long periods of time. In either
|
||||
* case, it would be infeasible to make use of high
|
||||
* resolution results for anything, so let's resort to old
|
||||
* behavior for this call. It's possible that in the
|
||||
* future, the user will want the high resolution timer, so
|
||||
* we don't disable it entirely.
|
||||
*/
|
||||
returnedTime = (PRInt64)lowresTime;
|
||||
needsCalibration = PR_FALSE;
|
||||
} else {
|
||||
/*
|
||||
* It is possible that when we recalibrate, we will return
|
||||
* a value less than what we have returned before; this is
|
||||
* unavoidable. We cannot tell the different between a
|
||||
* faulty QueryPerformanceCounter implementation and user
|
||||
* changes to the operating system time. Since we must
|
||||
* respect user changes to the operating system time, we
|
||||
* cannot maintain the invariant that Date.now() never
|
||||
* decreases; the old implementation has this behavior as
|
||||
* well.
|
||||
*/
|
||||
needsCalibration = PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
/* No detectable clock skew */
|
||||
returnedTime = (PRInt64)highresTime;
|
||||
needsCalibration = PR_FALSE;
|
||||
}
|
||||
} else {
|
||||
/* No high resolution timer is available, so fall back */
|
||||
returnedTime = (PRInt64)lowresTime;
|
||||
}
|
||||
} while (needsCalibration);
|
||||
|
||||
return returnedTime;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
PR_IMPLEMENT(PRTime)
|
||||
PR_Now(void)
|
||||
{
|
||||
|
@ -95,6 +331,8 @@ PR_Now(void)
|
|||
return prt;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
***********************************************************************
|
||||
|
|
|
@ -260,17 +260,6 @@ static DWORD dirAccessTable[] = {
|
|||
FILE_GENERIC_EXECUTE
|
||||
};
|
||||
|
||||
/*
|
||||
* The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
|
||||
* We store the value in a PRTime variable for convenience.
|
||||
* This constant is used by _PR_FileTimeToPRTime().
|
||||
*/
|
||||
#if defined(__MINGW32__)
|
||||
static const PRTime _pr_filetime_offset = 116444736000000000LL;
|
||||
#else
|
||||
static const PRTime _pr_filetime_offset = 116444736000000000i64;
|
||||
#endif
|
||||
|
||||
/* Windows CE has GetFileAttributesEx. */
|
||||
#ifndef WINCE
|
||||
typedef BOOL (WINAPI *GetFileAttributesExFn)(LPCTSTR,
|
||||
|
|
|
@ -604,6 +604,9 @@ void _PR_CleanupTime(void)
|
|||
monitor = NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef WINCE
|
||||
_MD_CleanupTime();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS)
|
||||
|
|
Загрузка…
Ссылка в новой задаче