diff --git a/js/src/configure.in b/js/src/configure.in index c782531a6f74..0a07acd7cd45 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -2449,6 +2449,28 @@ AC_PROG_GCC_TRADITIONAL AC_FUNC_MEMCMP AC_CHECK_FUNCS([getc_unlocked _getc_nolock gmtime_r localtime_r]) +dnl check for clock_gettime(), the CLOCK_MONOTONIC clock +AC_CACHE_CHECK(for clock_gettime(CLOCK_MONOTONIC), + ac_cv_clock_monotonic, + [for libs in "" -lrt; do + _SAVE_LIBS="$LIBS" + LIBS="$LIBS $libs" + AC_TRY_LINK([#include ], + [ struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); ], + ac_cv_clock_monotonic=$libs + LIBS="$_SAVE_LIBS" + break, + ac_cv_clock_monotonic=no) + LIBS="$_SAVE_LIBS" + done]) +if test "$ac_cv_clock_monotonic" != "no"; then + HAVE_CLOCK_MONOTONIC=1 + REALTIME_LIBS=$ac_cv_clock_monotonic + AC_DEFINE(HAVE_CLOCK_MONOTONIC) + AC_SUBST(HAVE_CLOCK_MONOTONIC) + AC_SUBST_LIST(REALTIME_LIBS) +fi dnl Checks for math functions. dnl ======================================================== diff --git a/xpcom/ds/TimeStamp.cpp b/mozglue/misc/TimeStamp.cpp similarity index 95% rename from xpcom/ds/TimeStamp.cpp rename to mozglue/misc/TimeStamp.cpp index 1d6a6c58d418..932b75c99571 100644 --- a/xpcom/ds/TimeStamp.cpp +++ b/mozglue/misc/TimeStamp.cpp @@ -9,7 +9,8 @@ */ #include "mozilla/TimeStamp.h" -#include "prenv.h" +#include +#include namespace mozilla { @@ -45,13 +46,13 @@ struct TimeStampInitialization static TimeStampInitialization sInitOnce; -TimeStamp +MFBT_API TimeStamp TimeStamp::ProcessCreation(bool& aIsInconsistent) { aIsInconsistent = false; if (sInitOnce.mProcessCreation.IsNull()) { - char* mozAppRestart = PR_GetEnv("MOZ_APP_RESTART"); + char* mozAppRestart = getenv("MOZ_APP_RESTART"); TimeStamp ts; /* When calling PR_SetEnv() with an empty value the existing variable may diff --git a/xpcom/ds/TimeStamp.h b/mozglue/misc/TimeStamp.h similarity index 96% rename from xpcom/ds/TimeStamp.h rename to mozglue/misc/TimeStamp.h index 94be768234d1..8f043d441161 100644 --- a/xpcom/ds/TimeStamp.h +++ b/mozglue/misc/TimeStamp.h @@ -12,8 +12,7 @@ #include "mozilla/Attributes.h" #include "mozilla/FloatingPoint.h" #include "mozilla/TypeTraits.h" -#include "nscore.h" -#include "nsDebug.h" +#include "mozilla/Types.h" namespace IPC { template struct ParamTraits; @@ -39,10 +38,10 @@ class TimeStamp; class BaseTimeDurationPlatformUtils { public: - static double ToSeconds(int64_t aTicks); - static double ToSecondsSigDigits(int64_t aTicks); - static int64_t TicksFromMilliseconds(double aMilliseconds); - static int64_t ResolutionInTicks(); + static MFBT_API double ToSeconds(int64_t aTicks); + static MFBT_API double ToSecondsSigDigits(int64_t aTicks); + static MFBT_API int64_t TicksFromMilliseconds(double aMilliseconds); + static MFBT_API int64_t ResolutionInTicks(); }; /** @@ -206,7 +205,6 @@ public: BaseTimeDuration operator*(const uint64_t aMultiplier) const { if (aMultiplier > INT64_MAX) { - NS_WARNING("Out-of-range multiplier when multiplying BaseTimeDuration"); return Forever(); } return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); @@ -428,8 +426,8 @@ public: * lower precision, usually 15.6 ms, but with very good performance benefit. * Use it for measurements of longer times, like >200ms timeouts. */ - static TimeStamp Now() { return Now(true); } - static TimeStamp NowLoRes() { return Now(false); } + static MFBT_API TimeStamp Now() { return Now(true); } + static MFBT_API TimeStamp NowLoRes() { return Now(false); } /** * Return a timestamp representing the time when the current process was @@ -443,14 +441,14 @@ public: * @returns A timestamp representing the time when the process was created, * this timestamp is always valid even when errors are reported */ - static TimeStamp ProcessCreation(bool& aIsInconsistent); + static MFBT_API TimeStamp ProcessCreation(bool& aIsInconsistent); /** * Records a process restart. After this call ProcessCreation() will return * the time when the browser was restarted instead of the actual time when * the process was created. */ - static void RecordProcessRestart(); + static MFBT_API void RecordProcessRestart(); /** * Compute the difference between two timestamps. Both must be non-null. @@ -536,8 +534,8 @@ public: // two TimeStamps, or scaling TimeStamps, is nonsense and must never // be allowed. - static nsresult Startup(); - static void Shutdown(); + static MFBT_API void Startup(); + static MFBT_API void Shutdown(); private: friend struct IPC::ParamTraits; @@ -545,7 +543,7 @@ private: MOZ_IMPLICIT TimeStamp(TimeStampValue aValue) : mValue(aValue) {} - static TimeStamp Now(bool aHighResolution); + static MFBT_API TimeStamp Now(bool aHighResolution); /** * Computes the uptime of the current process in microseconds. The result @@ -555,7 +553,7 @@ private: * @returns The number of microseconds since the calling process was started * or 0 if an error was encountered while computing the uptime */ - static uint64_t ComputeProcessUptime(); + static MFBT_API uint64_t ComputeProcessUptime(); /** * When built with PRIntervalTime, a value of 0 means this instance diff --git a/xpcom/ds/TimeStamp_darwin.cpp b/mozglue/misc/TimeStamp_darwin.cpp similarity index 97% rename from xpcom/ds/TimeStamp_darwin.cpp rename to mozglue/misc/TimeStamp_darwin.cpp index f9c3852dc559..f30bc9846057 100644 --- a/xpcom/ds/TimeStamp_darwin.cpp +++ b/mozglue/misc/TimeStamp_darwin.cpp @@ -23,7 +23,6 @@ #include #include "mozilla/TimeStamp.h" -#include "nsDebug.h" // Estimate of the smallest duration of time we can measure. static uint64_t sResolution; @@ -120,11 +119,11 @@ BaseTimeDurationPlatformUtils::ResolutionInTicks() return static_cast(sResolution); } -nsresult +void TimeStamp::Startup() { if (gInitialized) { - return NS_OK; + return; } mach_timebase_info_data_t timebaseInfo; @@ -133,7 +132,7 @@ TimeStamp::Startup() // to cache the result. kern_return_t kr = mach_timebase_info(&timebaseInfo); if (kr != KERN_SUCCESS) { - NS_RUNTIMEABORT("mach_timebase_info failed"); + MOZ_RELEASE_ASSERT(false, "mach_timebase_info failed"); } sNsPerTick = double(timebaseInfo.numer) / timebaseInfo.denom; @@ -149,7 +148,7 @@ TimeStamp::Startup() gInitialized = true; - return NS_OK; + return; } void diff --git a/xpcom/ds/TimeStamp_posix.cpp b/mozglue/misc/TimeStamp_posix.cpp similarity index 93% rename from xpcom/ds/TimeStamp_posix.cpp rename to mozglue/misc/TimeStamp_posix.cpp index 5a09c9c7a8f0..e9c4620d6b5e 100644 --- a/xpcom/ds/TimeStamp_posix.cpp +++ b/mozglue/misc/TimeStamp_posix.cpp @@ -48,10 +48,7 @@ #include "mozilla/Snprintf.h" #include "mozilla/TimeStamp.h" -#include "nsCRT.h" -#include "prprf.h" -#include "prthread.h" -#include "nsDebug.h" +#include // Estimate of the smallest duration of time we can measure. static uint64_t sResolution; @@ -171,16 +168,16 @@ BaseTimeDurationPlatformUtils::ResolutionInTicks() static bool gInitialized = false; -nsresult +void TimeStamp::Startup() { if (gInitialized) { - return NS_OK; + return; } struct timespec dummy; if (clock_gettime(CLOCK_MONOTONIC, &dummy) != 0) { - NS_RUNTIMEABORT("CLOCK_MONOTONIC is absent!"); + MOZ_CRASH("CLOCK_MONOTONIC is absent!"); } sResolution = ClockResolutionNs(); @@ -194,7 +191,7 @@ TimeStamp::Startup() gInitialized = true; - return NS_OK; + return; } void @@ -259,7 +256,7 @@ JiffiesSinceBoot(const char* aFile) // process uptime. This value will be stored at the address pointed by aTime; // if an error occurred 0 will be stored instead. -static void +static void* ComputeProcessUptimeThread(void* aTime) { uint64_t* uptime = static_cast(aTime); @@ -268,7 +265,7 @@ ComputeProcessUptimeThread(void* aTime) *uptime = 0; if (!hz) { - return; + return nullptr; } char threadStat[40]; @@ -278,10 +275,11 @@ ComputeProcessUptimeThread(void* aTime) uint64_t selfJiffies = JiffiesSinceBoot("/proc/self/stat"); if (!threadJiffies || !selfJiffies) { - return; + return nullptr; } *uptime = ((threadJiffies - selfJiffies) * kNsPerSec) / hz; + return nullptr; } // Computes and returns the process uptime in us on Linux & its derivatives. @@ -291,15 +289,14 @@ uint64_t TimeStamp::ComputeProcessUptime() { uint64_t uptime = 0; - PRThread* thread = PR_CreateThread(PR_USER_THREAD, - ComputeProcessUptimeThread, - &uptime, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_JOINABLE_THREAD, - 0); + pthread_t uptime_pthread; - PR_JoinThread(thread); + if (pthread_create(&uptime_pthread, nullptr, ComputeProcessUptimeThread, &uptime)) { + MOZ_CRASH("Failed to create process uptime thread."); + return 0; + } + + pthread_join(uptime_pthread, NULL); return uptime / kNsPerUs; } diff --git a/xpcom/ds/TimeStamp_windows.cpp b/mozglue/misc/TimeStamp_windows.cpp similarity index 95% rename from xpcom/ds/TimeStamp_windows.cpp rename to mozglue/misc/TimeStamp_windows.cpp index 15e3c2b00f2e..d53ef443ae21 100644 --- a/xpcom/ds/TimeStamp_windows.cpp +++ b/mozglue/misc/TimeStamp_windows.cpp @@ -8,37 +8,30 @@ // values of GetTickCount(). #include "mozilla/MathAlgorithms.h" -#include "mozilla/Mutex.h" #include "mozilla/TimeStamp.h" -#include "nsWindowsHelpers.h" + +#include +#include #include -#include "nsCRT.h" -#include "mozilla/Logging.h" -#include "prprf.h" -#include +// To enable logging define to your favorite logging API +#define LOG(x) -#include - -// Log module for mozilla::TimeStamp for Windows logging... -// -// To enable logging (see prlog.h for full details): -// -// set NSPR_LOG_MODULES=TimeStampWindows:5 -// set NSPR_LOG_FILE=nspr.log -// -// this enables LogLevel::Debug level information and places all output in -// the file nspr.log -static PRLogModuleInfo* -GetTimeStampLog() +class AutoCriticalSection { - static PRLogModuleInfo* sLog; - if (!sLog) { - sLog = PR_NewLogModule("TimeStampWindows"); +public: + AutoCriticalSection(LPCRITICAL_SECTION aSection) + : mSection(aSection) + { + ::EnterCriticalSection(mSection); } - return sLog; -} -#define LOG(x) MOZ_LOG(GetTimeStampLog(), mozilla::LogLevel::Debug, x) + ~AutoCriticalSection() + { + ::LeaveCriticalSection(mSection); + } +private: + LPCRITICAL_SECTION mSection; +}; // Estimate of the smallest duration of time we can measure. static volatile ULONGLONG sResolution; @@ -293,7 +286,7 @@ InitResolution() // ---------------------------------------------------------------------------- // TimeStampValue implementation // ---------------------------------------------------------------------------- - +MFBT_API TimeStampValue::TimeStampValue(ULONGLONG aGTC, ULONGLONG aQPC, bool aHasQPC) : mGTC(aGTC) , mQPC(aQPC) @@ -302,7 +295,7 @@ TimeStampValue::TimeStampValue(ULONGLONG aGTC, ULONGLONG aQPC, bool aHasQPC) { } -TimeStampValue& +MFBT_API TimeStampValue& TimeStampValue::operator+=(const int64_t aOther) { mGTC += aOther; @@ -310,7 +303,7 @@ TimeStampValue::operator+=(const int64_t aOther) return *this; } -TimeStampValue& +MFBT_API TimeStampValue& TimeStampValue::operator-=(const int64_t aOther) { mGTC -= aOther; @@ -320,7 +313,7 @@ TimeStampValue::operator-=(const int64_t aOther) // If the duration is less then two seconds, perform check of QPC stability // by comparing both GTC and QPC calculated durations of this and aOther. -uint64_t +MFBT_API uint64_t TimeStampValue::CheckQPC(const TimeStampValue& aOther) const { uint64_t deltaGTC = mGTC - aOther.mGTC; @@ -394,7 +387,7 @@ TimeStampValue::CheckQPC(const TimeStampValue& aOther) const return deltaGTC; } -uint64_t +MFBT_API uint64_t TimeStampValue::operator-(const TimeStampValue& aOther) const { if (mIsNull && aOther.mIsNull) { @@ -408,14 +401,14 @@ TimeStampValue::operator-(const TimeStampValue& aOther) const // TimeDuration and TimeStamp implementation // ---------------------------------------------------------------------------- -double +MFBT_API double BaseTimeDurationPlatformUtils::ToSeconds(int64_t aTicks) { // Converting before arithmetic avoids blocked store forward return double(aTicks) / (double(sFrequencyPerSec) * 1000.0); } -double +MFBT_API double BaseTimeDurationPlatformUtils::ToSecondsSigDigits(int64_t aTicks) { // don't report a value < mResolution ... @@ -427,7 +420,7 @@ BaseTimeDurationPlatformUtils::ToSecondsSigDigits(int64_t aTicks) return double(valueSigDigs) / kNsPerSecd; } -int64_t +MFBT_API int64_t BaseTimeDurationPlatformUtils::TicksFromMilliseconds(double aMilliseconds) { double result = ms2mt(aMilliseconds); @@ -440,7 +433,7 @@ BaseTimeDurationPlatformUtils::TicksFromMilliseconds(double aMilliseconds) return result; } -int64_t +MFBT_API int64_t BaseTimeDurationPlatformUtils::ResolutionInTicks() { return static_cast(sResolution); @@ -482,7 +475,7 @@ HasStableTSC() return regs[3] & (1 << 8); } -nsresult +MFBT_API void TimeStamp::Startup() { // Decide which implementation to use for the high-performance timer. @@ -508,7 +501,7 @@ TimeStamp::Startup() InitResolution(); LOG(("TimeStamp: using GetTickCount")); - return NS_OK; + return; } sFrequencyPerSec = freq.QuadPart; @@ -517,16 +510,16 @@ TimeStamp::Startup() InitThresholds(); InitResolution(); - return NS_OK; + return; } -void +MFBT_API void TimeStamp::Shutdown() { DeleteCriticalSection(&sTimeStampLock); } -TimeStamp +MFBT_API TimeStamp TimeStamp::Now(bool aHighResolution) { // sUseQPC is volatile @@ -541,7 +534,7 @@ TimeStamp::Now(bool aHighResolution) // Computes and returns the process uptime in microseconds. // Returns 0 if an error was encountered. -uint64_t +MFBT_API uint64_t TimeStamp::ComputeProcessUptime() { SYSTEMTIME nowSys; diff --git a/xpcom/ds/TimeStamp_windows.h b/mozglue/misc/TimeStamp_windows.h similarity index 83% rename from xpcom/ds/TimeStamp_windows.h rename to mozglue/misc/TimeStamp_windows.h index c746db6ac9fe..28ab59f93436 100644 --- a/xpcom/ds/TimeStamp_windows.h +++ b/mozglue/misc/TimeStamp_windows.h @@ -7,6 +7,8 @@ #ifndef mozilla_TimeStamp_windows_h #define mozilla_TimeStamp_windows_h +#include "mozilla/Types.h" + namespace mozilla { class TimeStamp; @@ -23,9 +25,9 @@ class TimeStampValue bool mHasQPC; bool mIsNull; - TimeStampValue(uint64_t aGTC, uint64_t aQPC, bool aHasQPC); + MFBT_API TimeStampValue(uint64_t aGTC, uint64_t aQPC, bool aHasQPC); - uint64_t CheckQPC(const TimeStampValue& aOther) const; + MFBT_API uint64_t CheckQPC(const TimeStampValue& aOther) const; struct _SomethingVeryRandomHere; MOZ_CONSTEXPR TimeStampValue(_SomethingVeryRandomHere* aNullValue) @@ -37,7 +39,7 @@ class TimeStampValue } public: - uint64_t operator-(const TimeStampValue& aOther) const; + MFBT_API uint64_t operator-(const TimeStampValue& aOther) const; TimeStampValue operator+(const int64_t aOther) const { @@ -47,8 +49,8 @@ public: { return TimeStampValue(mGTC - aOther, mQPC - aOther, mHasQPC); } - TimeStampValue& operator+=(const int64_t aOther); - TimeStampValue& operator-=(const int64_t aOther); + MFBT_API TimeStampValue& operator+=(const int64_t aOther); + MFBT_API TimeStampValue& operator-=(const int64_t aOther); bool operator<(const TimeStampValue& aOther) const { diff --git a/mozglue/misc/moz.build b/mozglue/misc/moz.build new file mode 100644 index 000000000000..b3bc6af24eeb --- /dev/null +++ b/mozglue/misc/moz.build @@ -0,0 +1,35 @@ +FINAL_LIBRARY = 'mozglue' + +EXPORTS.mozilla += [ + 'TimeStamp.h', +] + +if CONFIG['OS_ARCH'] == 'WINNT': + EXPORTS.mozilla += [ + 'TimeStamp_windows.h', + ] + +SOURCES += [ + 'TimeStamp.cpp', +] + +OS_LIBS += CONFIG['REALTIME_LIBS'] + +DEFINES['IMPL_MFBT'] = True + +if CONFIG['OS_ARCH'] == 'WINNT': + SOURCES += [ + 'TimeStamp_windows.cpp', + ] +elif CONFIG['HAVE_CLOCK_MONOTONIC']: + SOURCES += [ + 'TimeStamp_posix.cpp', + ] +elif CONFIG['OS_ARCH'] == 'Darwin': + SOURCES += [ + 'TimeStamp_darwin.cpp', + ] +elif CONFIG['COMPILE_ENVIRONMENT']: + error('No TimeStamp implementation on this platform. Build will not succeed') + +FAIL_ON_WARNINGS = True diff --git a/mozglue/moz.build b/mozglue/moz.build index 12907d75d943..d2fa07e814de 100644 --- a/mozglue/moz.build +++ b/mozglue/moz.build @@ -10,7 +10,10 @@ if CONFIG['MOZ_LINKER']: if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': DIRS += ['android'] -DIRS += ['build'] +DIRS += [ + 'build', + 'misc', +] if CONFIG['MOZ_CRT']: DIRS += ['crt'] diff --git a/xpcom/build/NSPRInterposer.cpp b/xpcom/build/NSPRInterposer.cpp index 2976259cee96..29c1a53dcdca 100644 --- a/xpcom/build/NSPRInterposer.cpp +++ b/xpcom/build/NSPRInterposer.cpp @@ -9,6 +9,8 @@ #include "prio.h" #include "private/pprio.h" +#include "nsDebug.h" +#include "nscore.h" namespace { diff --git a/xpcom/ds/moz.build b/xpcom/ds/moz.build index 35ec5d675b19..3cb301a512b0 100644 --- a/xpcom/ds/moz.build +++ b/xpcom/ds/moz.build @@ -36,7 +36,6 @@ if CONFIG['OS_ARCH'] == 'WINNT': 'nsIWindowsRegKey.idl', ] EXPORTS += ['nsWindowsRegKey.h'] - EXPORTS.mozilla += ['TimeStamp_windows.h'] SOURCES += [ 'nsWindowsRegKey.cpp' ] @@ -63,7 +62,6 @@ EXPORTS += [ EXPORTS.mozilla += [ 'StickyTimeDuration.h', - 'TimeStamp.h', ] UNIFIED_SOURCES += [ @@ -81,7 +79,6 @@ UNIFIED_SOURCES += [ 'nsSupportsArrayEnumerator.cpp', 'nsSupportsPrimitives.cpp', 'nsVariant.cpp', - 'TimeStamp.cpp', ] # These two files cannot be built in unified mode because they use the @@ -91,21 +88,6 @@ SOURCES += [ 'nsStaticNameTable.cpp', ] -if CONFIG['OS_ARCH'] == 'WINNT': - SOURCES += [ - 'TimeStamp_windows.cpp', - ] -elif CONFIG['HAVE_CLOCK_MONOTONIC']: - SOURCES += [ - 'TimeStamp_posix.cpp', - ] -elif CONFIG['OS_ARCH'] == 'Darwin': - SOURCES += [ - 'TimeStamp_darwin.cpp', - ] -elif CONFIG['COMPILE_ENVIRONMENT']: - error('No TimeStamp implementation on this platform. Build will not succeed') - EXTRA_COMPONENTS += [ 'nsINIProcessor.js', 'nsINIProcessor.manifest', diff --git a/xpcom/libxpcomrt/moz.build b/xpcom/libxpcomrt/moz.build index 4de8bb0eb06d..922de9053d80 100644 --- a/xpcom/libxpcomrt/moz.build +++ b/xpcom/libxpcomrt/moz.build @@ -43,20 +43,7 @@ xpcom_ds_src = [ 'nsStringEnumerator.cpp', 'nsSupportsPrimitives.cpp', ] -if CONFIG['OS_ARCH'] == 'WINNT': - xpcom_ds_src += [ - 'TimeStamp_windows.cpp', - ] -elif CONFIG['HAVE_CLOCK_MONOTONIC']: - xpcom_ds_src += [ - 'TimeStamp_posix.cpp', - ] -elif CONFIG['OS_ARCH'] == 'Darwin': - xpcom_ds_src += [ - 'TimeStamp_darwin.cpp', - ] -elif CONFIG['COMPILE_ENVIRONMENT']: - error('No TimeStamp implementation on this platform. Build will not succeed') + src_list += [ '/xpcom/ds/%s' % s for s in xpcom_ds_src ]