mirror of
https://github.com/apache/impala.git
synced 2025-12-20 10:29:58 -05:00
IMPALA-4631: don't use floating point operations for time unit conversions
This was leading to the PlanFragmentExecutor::Close() DCHECK because with floating point we can have c * a + c * b > c * (a + b). Also note this is much more likely to happen when using the MONOTONIC_COARSE since that will result in the nested scoped timers ending up starting/stopping at exactly the same time. Additionally, the new code is faster. Change-Id: I7237f579b201f5bd3930f66e9c2c8d700c37ffeb Reviewed-on: http://gerrit.cloudera.org:8080/5434 Reviewed-by: Dan Hecht <dhecht@cloudera.com> Tested-by: Jim Apple <jbapple-impala@apache.org>
This commit is contained in:
@@ -166,18 +166,6 @@ bool WallTime_Parse_Timezone(const char* time_spec,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
WallTime WallTime_Now() {
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
mach_timespec_t ts;
|
|
||||||
walltime_internal::GetCurrentTime(&ts);
|
|
||||||
return ts.tv_sec + ts.tv_nsec / static_cast<double>(1e9);
|
|
||||||
#else
|
|
||||||
timespec ts;
|
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
|
||||||
return ts.tv_sec + ts.tv_nsec / static_cast<double>(1e9);
|
|
||||||
#endif // defined(__APPLE__)
|
|
||||||
}
|
|
||||||
|
|
||||||
void StringAppendStrftime(string* dst,
|
void StringAppendStrftime(string* dst,
|
||||||
const char* format,
|
const char* format,
|
||||||
time_t when,
|
time_t when,
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ using std::string;
|
|||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "gutil/integral_types.h"
|
#include "gutil/integral_types.h"
|
||||||
|
|
||||||
|
#define NANOS_PER_SEC 1000000000ll
|
||||||
|
#define NANOS_PER_MICRO 1000ll
|
||||||
|
#define MICROS_PER_SEC 1000000ll
|
||||||
|
#define MICROS_PER_MILLI 1000ll
|
||||||
|
#define MILLIS_PER_SEC 1000ll
|
||||||
|
|
||||||
typedef double WallTime;
|
typedef double WallTime;
|
||||||
|
|
||||||
// Append result to a supplied string.
|
// Append result to a supplied string.
|
||||||
@@ -52,9 +58,6 @@ bool WallTime_Parse_Timezone(const char* time_spec,
|
|||||||
bool local,
|
bool local,
|
||||||
WallTime* result);
|
WallTime* result);
|
||||||
|
|
||||||
// Return current time in seconds as a WallTime.
|
|
||||||
WallTime WallTime_Now();
|
|
||||||
|
|
||||||
typedef int64 MicrosecondsInt64;
|
typedef int64 MicrosecondsInt64;
|
||||||
typedef int64 NanosecondsInt64;
|
typedef int64 NanosecondsInt64;
|
||||||
|
|
||||||
@@ -76,7 +79,7 @@ inline void GetCurrentTime(mach_timespec_t* ts) {
|
|||||||
inline MicrosecondsInt64 GetCurrentTimeMicros() {
|
inline MicrosecondsInt64 GetCurrentTimeMicros() {
|
||||||
mach_timespec_t ts;
|
mach_timespec_t ts;
|
||||||
GetCurrentTime(&ts);
|
GetCurrentTime(&ts);
|
||||||
return ts.tv_sec * 1e6 + ts.tv_nsec / 1e3;
|
return ts.tv_sec * MICROS_PER_SEC + ts.tv_nsec / NANOS_PER_MICRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int64_t GetMonoTimeNanos() {
|
inline int64_t GetMonoTimeNanos() {
|
||||||
@@ -91,7 +94,7 @@ inline int64_t GetMonoTimeNanos() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline MicrosecondsInt64 GetMonoTimeMicros() {
|
inline MicrosecondsInt64 GetMonoTimeMicros() {
|
||||||
return GetMonoTimeNanos() / 1e3;
|
return GetMonoTimeNanos() / NANOS_PER_MICRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MicrosecondsInt64 GetThreadCpuTimeMicros() {
|
inline MicrosecondsInt64 GetThreadCpuTimeMicros() {
|
||||||
@@ -117,7 +120,8 @@ inline MicrosecondsInt64 GetThreadCpuTimeMicros() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return thread_info_data.user_time.seconds * 1e6 + thread_info_data.user_time.microseconds;
|
return thread_info_data.user_time.seconds * MICROS_PER_SEC +
|
||||||
|
thread_info_data.user_time.microseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -125,13 +129,13 @@ inline MicrosecondsInt64 GetThreadCpuTimeMicros() {
|
|||||||
inline MicrosecondsInt64 GetClockTimeMicros(clockid_t clock) {
|
inline MicrosecondsInt64 GetClockTimeMicros(clockid_t clock) {
|
||||||
timespec ts;
|
timespec ts;
|
||||||
clock_gettime(clock, &ts);
|
clock_gettime(clock, &ts);
|
||||||
return ts.tv_sec * 1e6 + ts.tv_nsec / 1e3;
|
return ts.tv_sec * MICROS_PER_SEC + ts.tv_nsec / NANOS_PER_MICRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NanosecondsInt64 GetClockTimeNanos(clockid_t clock) {
|
inline NanosecondsInt64 GetClockTimeNanos(clockid_t clock) {
|
||||||
timespec ts;
|
timespec ts;
|
||||||
clock_gettime(clock, &ts);
|
clock_gettime(clock, &ts);
|
||||||
return ts.tv_sec * 1e9 + ts.tv_nsec;
|
return ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(__APPLE__)
|
#endif // defined(__APPLE__)
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ class MonotonicStopWatch {
|
|||||||
// Now() can be called frequently (IMPALA-2407).
|
// Now() can be called frequently (IMPALA-2407).
|
||||||
timespec ts;
|
timespec ts;
|
||||||
clock_gettime(OsInfo::fast_clock(), &ts);
|
clock_gettime(OsInfo::fast_clock(), &ts);
|
||||||
return ts.tv_sec * 1e9 + ts.tv_nsec;
|
return ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ inline int64_t MonotonicMicros() { // 63 bits ~= 5K years uptime
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline int64_t MonotonicMillis() {
|
inline int64_t MonotonicMillis() {
|
||||||
return GetMonoTimeMicros() / 1e3;
|
return GetMonoTimeMicros() / MICROS_PER_MILLI;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int64_t MonotonicSeconds() {
|
inline int64_t MonotonicSeconds() {
|
||||||
return GetMonoTimeMicros() / 1e6;
|
return GetMonoTimeMicros() / MICROS_PER_SEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ inline int64_t MonotonicSeconds() {
|
|||||||
/// a cluster. For more accurate timings on the local host use the monotonic functions
|
/// a cluster. For more accurate timings on the local host use the monotonic functions
|
||||||
/// above.
|
/// above.
|
||||||
inline int64_t UnixMillis() {
|
inline int64_t UnixMillis() {
|
||||||
return GetCurrentTimeMicros() / 1e3;
|
return GetCurrentTimeMicros() / MICROS_PER_MILLI;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sleeps the current thread for at least duration_ms milliseconds.
|
/// Sleeps the current thread for at least duration_ms milliseconds.
|
||||||
|
|||||||
Reference in New Issue
Block a user