Remove base/threading and base/time
Change-Id: I6dec7ba59f53e03fc81b877820b9e8fe1fbf6c84
Reviewed-on: https://gn-review.googlesource.com/1721
Commit-Queue: Scott Graham <scottmg@chromium.org>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/base/files/file.h b/base/files/file.h
index e000636..61239ad 100644
--- a/base/files/file.h
+++ b/base/files/file.h
@@ -13,8 +13,8 @@
#include "base/files/platform_file.h"
#include "base/files/scoped_file.h"
#include "base/macros.h"
-#include "base/time/time.h"
#include "util/build_config.h"
+#include "util/ticks.h"
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
#include <sys/stat.h>
@@ -132,13 +132,13 @@
bool is_symbolic_link;
// The last modified time of a file.
- Time last_modified;
+ Ticks last_modified;
// The last accessed time of a file.
- Time last_accessed;
+ Ticks last_accessed;
// The creation time of a file.
- Time creation_time;
+ Ticks creation_time;
};
File();
@@ -249,9 +249,6 @@
// 0.01 % > 7.6 seconds
bool Flush();
- // Updates the file times.
- bool SetTimes(Time last_access_time, Time last_modified_time);
-
// Returns some basic information for the given file.
bool GetInfo(Info* info);
diff --git a/base/files/file_enumerator.h b/base/files/file_enumerator.h
index edd5036..81f757b 100644
--- a/base/files/file_enumerator.h
+++ b/base/files/file_enumerator.h
@@ -13,8 +13,8 @@
#include "base/containers/stack.h"
#include "base/files/file_path.h"
#include "base/macros.h"
-#include "base/time/time.h"
#include "util/build_config.h"
+#include "util/ticks.h"
#if defined(OS_WIN)
#include <windows.h>
@@ -52,7 +52,7 @@
FilePath GetName() const;
int64_t GetSize() const;
- Time GetLastModifiedTime() const;
+ Ticks GetLastModifiedTime() const;
#if defined(OS_WIN)
// Note that the cAlternateFileName (used to hold the "short" 8.3 name)
diff --git a/base/files/file_enumerator_posix.cc b/base/files/file_enumerator_posix.cc
index 003f045..41d52b8 100644
--- a/base/files/file_enumerator_posix.cc
+++ b/base/files/file_enumerator_posix.cc
@@ -49,8 +49,8 @@
return stat_.st_size;
}
-base::Time FileEnumerator::FileInfo::GetLastModifiedTime() const {
- return base::Time::FromTimeT(stat_.st_mtime);
+Ticks FileEnumerator::FileInfo::GetLastModifiedTime() const {
+ return stat_.st_mtime;
}
// FileEnumerator --------------------------------------------------------------
diff --git a/base/files/file_enumerator_win.cc b/base/files/file_enumerator_win.cc
index a2bfabf..803b7bd 100644
--- a/base/files/file_enumerator_win.cc
+++ b/base/files/file_enumerator_win.cc
@@ -54,8 +54,8 @@
return static_cast<int64_t>(size.QuadPart);
}
-base::Time FileEnumerator::FileInfo::GetLastModifiedTime() const {
- return base::Time::FromFileTime(find_data_.ftLastWriteTime);
+Ticks FileEnumerator::FileInfo::GetLastModifiedTime() const {
+ return *reinterpret_cast<const uint64_t*>(&find_data_.ftLastWriteTime);
}
// FileEnumerator --------------------------------------------------------------
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index c4f1080..977eb1b 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -46,23 +46,6 @@
return HANDLE_EINTR(ftruncate(file, length));
}
-int CallFutimes(PlatformFile file, const struct timeval times[2]) {
-#ifdef __USE_XOPEN2K8
- // futimens should be available, but futimes might not be
- // http://pubs.opengroup.org/onlinepubs/9699919799/
-
- timespec ts_times[2];
- ts_times[0].tv_sec = times[0].tv_sec;
- ts_times[0].tv_nsec = times[0].tv_usec * 1000;
- ts_times[1].tv_sec = times[1].tv_sec;
- ts_times[1].tv_nsec = times[1].tv_usec * 1000;
-
- return futimens(file, ts_times);
-#else
- return futimes(file, times);
-#endif
-}
-
#if !defined(OS_FUCHSIA)
File::Error CallFcntlFlock(PlatformFile file, bool do_lock) {
struct flock lock;
@@ -90,11 +73,6 @@
return 0;
}
-int CallFutimes(PlatformFile file, const struct timeval times[2]) {
- NOTIMPLEMENTED(); // NaCl doesn't implement futimes.
- return 0;
-}
-
File::Error CallFcntlFlock(PlatformFile file, bool do_lock) {
NOTIMPLEMENTED(); // NaCl doesn't implement flock struct.
return File::FILE_ERROR_INVALID_OPERATION;
@@ -126,17 +104,10 @@
#error
#endif
- last_modified = Time::FromTimeT(last_modified_sec) +
- TimeDelta::FromMicroseconds(last_modified_nsec /
- Time::kNanosecondsPerMicrosecond);
-
- last_accessed = Time::FromTimeT(last_accessed_sec) +
- TimeDelta::FromMicroseconds(last_accessed_nsec /
- Time::kNanosecondsPerMicrosecond);
-
- creation_time = Time::FromTimeT(creation_time_sec) +
- TimeDelta::FromMicroseconds(creation_time_nsec /
- Time::kNanosecondsPerMicrosecond);
+ constexpr uint64_t kNano = 1'000'000'000;
+ last_modified = last_modified_sec * kNano + last_modified_nsec;
+ last_accessed = last_accessed_sec * kNano + last_accessed_nsec;
+ creation_time = creation_time_sec * kNano + creation_time_nsec;
}
bool File::IsValid() const {
@@ -281,16 +252,6 @@
return !CallFtruncate(file_.get(), length);
}
-bool File::SetTimes(Time last_access_time, Time last_modified_time) {
- DCHECK(IsValid());
-
- timeval times[2];
- times[0] = last_access_time.ToTimeVal();
- times[1] = last_modified_time.ToTimeVal();
-
- return !CallFutimes(file_.get(), times);
-}
-
bool File::GetInfo(Info* info) {
DCHECK(IsValid());
diff --git a/base/files/file_util.cc b/base/files/file_util.cc
index 674dd27..d087b00 100644
--- a/base/files/file_util.cc
+++ b/base/files/file_util.cc
@@ -218,23 +218,6 @@
return true;
}
-bool TouchFile(const FilePath& path,
- const Time& last_accessed,
- const Time& last_modified) {
- int flags = File::FLAG_OPEN | File::FLAG_WRITE_ATTRIBUTES;
-
-#if defined(OS_WIN)
- // On Windows, FILE_FLAG_BACKUP_SEMANTICS is needed to open a directory.
- if (DirectoryExists(path))
- flags |= File::FLAG_BACKUP_SEMANTICS;
-#endif // OS_WIN
-
- File file(path, flags);
- if (!file.IsValid())
- return false;
-
- return file.SetTimes(last_accessed, last_modified);
-}
#endif // !defined(OS_NACL_NONSFI)
bool CloseFile(FILE* file) {
diff --git a/base/files/file_util.h b/base/files/file_util.h
index 90f9cd6..bfcac01 100644
--- a/base/files/file_util.h
+++ b/base/files/file_util.h
@@ -36,7 +36,6 @@
namespace base {
class Environment;
-class Time;
//-----------------------------------------------------------------------------
// Functions that involve filesystem access or modification:
@@ -322,11 +321,6 @@
// Returns information about the given file path.
bool GetFileInfo(const FilePath& file_path, File::Info* info);
-// Sets the time of the last access and the time of the last modification.
-bool TouchFile(const FilePath& path,
- const Time& last_accessed,
- const Time& last_modified);
-
// Wrapper for fopen-like calls. Returns non-NULL FILE* on success. The
// underlying file descriptor (POSIX) or handle (Windows) is unconditionally
// configured to not be propagated to child processes.
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc
index 4c1360f..9415735 100644
--- a/base/files/file_util_posix.cc
+++ b/base/files/file_util_posix.cc
@@ -36,7 +36,6 @@
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
#include "util/build_config.h"
#if defined(OS_MACOSX)
diff --git a/base/files/file_util_win.cc b/base/files/file_util_win.cc
index 9133d7e..2a1e9ec 100644
--- a/base/files/file_util_win.cc
+++ b/base/files/file_util_win.cc
@@ -28,7 +28,6 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
#include "base/win/scoped_handle.h"
// #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the
@@ -704,9 +703,9 @@
results->is_directory =
(attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
- results->last_modified = Time::FromFileTime(attr.ftLastWriteTime);
- results->last_accessed = Time::FromFileTime(attr.ftLastAccessTime);
- results->creation_time = Time::FromFileTime(attr.ftCreationTime);
+ results->last_modified = *reinterpret_cast<uint64_t*>(&attr.ftLastWriteTime);
+ results->last_accessed = *reinterpret_cast<uint64_t*>(&attr.ftLastAccessTime);
+ results->creation_time = *reinterpret_cast<uint64_t*>(&attr.ftCreationTime);
return true;
}
diff --git a/base/files/file_win.cc b/base/files/file_win.cc
index 401ac33..7ca4461 100644
--- a/base/files/file_win.cc
+++ b/base/files/file_win.cc
@@ -169,15 +169,6 @@
FALSE));
}
-bool File::SetTimes(Time last_access_time, Time last_modified_time) {
- DCHECK(IsValid());
-
- FILETIME last_access_filetime = last_access_time.ToFileTime();
- FILETIME last_modified_filetime = last_modified_time.ToFileTime();
- return (::SetFileTime(file_.Get(), NULL, &last_access_filetime,
- &last_modified_filetime) != FALSE);
-}
-
bool File::GetInfo(Info* info) {
DCHECK(IsValid());
@@ -192,9 +183,11 @@
info->is_directory =
(file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info->is_symbolic_link = false; // Windows doesn't have symbolic links.
- info->last_modified = Time::FromFileTime(file_info.ftLastWriteTime);
- info->last_accessed = Time::FromFileTime(file_info.ftLastAccessTime);
- info->creation_time = Time::FromFileTime(file_info.ftCreationTime);
+ info->last_modified =
+ *reinterpret_cast<uint64_t*>(&file_info.ftLastWriteTime);
+ info->last_accessed =
+ *reinterpret_cast<uint64_t*>(&file_info.ftLastAccessTime);
+ info->creation_time = *reinterpret_cast<uint64_t*>(&file_info.ftCreationTime);
return true;
}
diff --git a/base/json/json_perftest.cc b/base/json/json_perftest.cc
deleted file mode 100644
index fc05bdc..0000000
--- a/base/json/json_perftest.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.h"
-
-namespace base {
-
-namespace {
-// Generates a simple dictionary value with simple data types, a string and a
-// list.
-std::unique_ptr<DictionaryValue> GenerateDict() {
- auto root = std::make_unique<DictionaryValue>();
- root->SetDouble("Double", 3.141);
- root->SetBoolean("Bool", true);
- root->SetInteger("Int", 42);
- root->SetString("String", "Foo");
-
- auto list = std::make_unique<ListValue>();
- list->Set(0, std::make_unique<Value>(2.718));
- list->Set(1, std::make_unique<Value>(false));
- list->Set(2, std::make_unique<Value>(123));
- list->Set(3, std::make_unique<Value>("Bar"));
- root->Set("List", std::move(list));
-
- return root;
-}
-
-// Generates a tree-like dictionary value with a size of O(breadth ** depth).
-std::unique_ptr<DictionaryValue> GenerateLayeredDict(int breadth, int depth) {
- if (depth == 1)
- return GenerateDict();
-
- auto root = GenerateDict();
- auto next = GenerateLayeredDict(breadth, depth - 1);
-
- for (int i = 0; i < breadth; ++i) {
- root->Set("Dict" + std::to_string(i), next->CreateDeepCopy());
- }
-
- return root;
-}
-
-} // namespace
-
-class JSONPerfTest : public testing::Test {
- public:
- void TestWriteAndRead(int breadth, int depth) {
- std::string description = "Breadth: " + std::to_string(breadth) +
- ", Depth: " + std::to_string(depth);
- auto dict = GenerateLayeredDict(breadth, depth);
- std::string json;
-
- TimeTicks start_write = TimeTicks::Now();
- JSONWriter::Write(*dict, &json);
- TimeTicks end_write = TimeTicks::Now();
- perf_test::PrintResult("Write", "", description,
- (end_write - start_write).InMillisecondsF(), "ms",
- true);
-
- TimeTicks start_read = TimeTicks::Now();
- JSONReader::Read(json);
- TimeTicks end_read = TimeTicks::Now();
- perf_test::PrintResult("Read", "", description,
- (end_read - start_read).InMillisecondsF(), "ms",
- true);
- }
-};
-
-TEST_F(JSONPerfTest, StressTest) {
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 12; ++j) {
- TestWriteAndRead(i + 1, j + 1);
- }
- }
-}
-
-} // namespace base
diff --git a/base/logging.cc b/base/logging.cc
index f0ce6f5..c381a28 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -7,6 +7,8 @@
#include <limits.h>
#include <stdint.h>
+#include <thread>
+
#include "base/macros.h"
#include "util/build_config.h"
@@ -19,6 +21,7 @@
#define STDERR_FILENO 2
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
+#include <sys/time.h>
#include <time.h>
#endif
@@ -49,7 +52,6 @@
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/threading/platform_thread.h"
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
#include "base/posix/safe_strerror.h"
@@ -195,7 +197,7 @@
// TODO(darin): It might be nice if the columns were fixed width.
stream_ << '[';
- stream_ << base::PlatformThread::CurrentId() << ':';
+ stream_ << std::this_thread::get_id() << ':';
#if defined(OS_WIN)
SYSTEMTIME local_time;
GetLocalTime(&local_time);
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h
deleted file mode 100644
index 8b814c5..0000000
--- a/base/threading/platform_thread.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// WARNING: You should *NOT* be using this class directly. PlatformThread is
-// the low-level platform-specific abstraction to the OS's threading interface.
-// You should instead be using a message-loop driven Thread, see thread.h.
-
-#ifndef BASE_THREADING_PLATFORM_THREAD_H_
-#define BASE_THREADING_PLATFORM_THREAD_H_
-
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "util/build_config.h"
-
-#if defined(OS_WIN)
-#include "base/win/windows_types.h"
-#elif defined(OS_MACOSX)
-#include <mach/mach_types.h>
-#elif defined(OS_POSIX)
-#include <pthread.h>
-#include <unistd.h>
-#endif
-
-namespace base {
-
-// Used for logging. Always an integer value.
-#if defined(OS_WIN)
-typedef DWORD PlatformThreadId;
-#elif defined(OS_MACOSX)
-typedef mach_port_t PlatformThreadId;
-#elif defined(OS_POSIX)
-typedef pid_t PlatformThreadId;
-#endif
-
-// Used for thread checking and debugging.
-// Meant to be as fast as possible.
-// These are produced by PlatformThread::CurrentRef(), and used to later
-// check if we are on the same thread or not by using ==. These are safe
-// to copy between threads, but can't be copied to another process as they
-// have no meaning there. Also, the internal identifier can be re-used
-// after a thread dies, so a PlatformThreadRef cannot be reliably used
-// to distinguish a new thread from an old, dead thread.
-class PlatformThreadRef {
- public:
-#if defined(OS_WIN)
- typedef DWORD RefType;
-#else // OS_POSIX
- typedef pthread_t RefType;
-#endif
- constexpr PlatformThreadRef() : id_(0) {}
-
- explicit constexpr PlatformThreadRef(RefType id) : id_(id) {}
-
- bool operator==(PlatformThreadRef other) const { return id_ == other.id_; }
-
- bool operator!=(PlatformThreadRef other) const { return id_ != other.id_; }
-
- bool is_null() const { return id_ == 0; }
-
- private:
- RefType id_;
-};
-
-// Used to operate on threads.
-class PlatformThreadHandle {
- public:
-#if defined(OS_WIN)
- typedef void* Handle;
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
- typedef pthread_t Handle;
-#endif
-
- constexpr PlatformThreadHandle() : handle_(0) {}
-
- explicit constexpr PlatformThreadHandle(Handle handle) : handle_(handle) {}
-
- bool is_equal(const PlatformThreadHandle& other) const {
- return handle_ == other.handle_;
- }
-
- bool is_null() const { return !handle_; }
-
- Handle platform_handle() const { return handle_; }
-
- private:
- Handle handle_;
-};
-
-const PlatformThreadId kInvalidThreadId(0);
-
-// A namespace for low-level thread functions.
-class PlatformThread {
- public:
- // Implement this interface to run code on a background thread. Your
- // ThreadMain method will be called on the newly created thread.
- class Delegate {
- public:
- virtual void ThreadMain() = 0;
-
- protected:
- virtual ~Delegate() = default;
- };
-
- // Gets the current thread id, which may be useful for logging purposes.
- static PlatformThreadId CurrentId();
-
- // Gets the current thread reference, which can be used to check if
- // we're on the right thread quickly.
- static PlatformThreadRef CurrentRef();
-
- // Get the handle representing the current thread. On Windows, this is a
- // pseudo handle constant which will always represent the thread using it and
- // hence should not be shared with other threads nor be used to differentiate
- // the current thread from another.
- static PlatformThreadHandle CurrentHandle();
-
- // Yield the current thread so another thread can be scheduled.
- static void YieldCurrentThread();
-
- // Sleeps for the specified duration.
- static void Sleep(base::TimeDelta duration);
-
- // Creates a new thread. The |stack_size| parameter can be 0 to indicate
- // that the default stack size should be used. Upon success,
- // |*thread_handle| will be assigned a handle to the newly created thread,
- // and |delegate|'s ThreadMain method will be executed on the newly created
- // thread.
- // NOTE: When you are done with the thread handle, you must call Join to
- // release system resources associated with the thread. You must ensure that
- // the Delegate object outlives the thread.
- static bool Create(size_t stack_size,
- Delegate* delegate,
- PlatformThreadHandle* thread_handle);
-
- // CreateNonJoinable() does the same thing as Create() except the thread
- // cannot be Join()'d. Therefore, it also does not output a
- // PlatformThreadHandle.
- static bool CreateNonJoinable(size_t stack_size, Delegate* delegate);
-
- // Joins with a thread created via the Create function. This function blocks
- // the caller until the designated thread exits. This will invalidate
- // |thread_handle|.
- static void Join(PlatformThreadHandle thread_handle);
-
- // Detaches and releases the thread handle. The thread is no longer joinable
- // and |thread_handle| is invalidated after this call.
- static void Detach(PlatformThreadHandle thread_handle);
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformThread);
-};
-
-} // namespace base
-
-#endif // BASE_THREADING_PLATFORM_THREAD_H_
diff --git a/base/threading/platform_thread_linux.cc b/base/threading/platform_thread_linux.cc
deleted file mode 100644
index 1833c54..0000000
--- a/base/threading/platform_thread_linux.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/threading/platform_thread.h"
-
-#include <errno.h>
-#include <sched.h>
-#include <stddef.h>
-
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "util/build_config.h"
-
-#if !defined(OS_NACL) && !defined(OS_AIX)
-#include <pthread.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-
-namespace base {
-
-void InitThreading() {}
-
-void TerminateOnThread() {}
-
-size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
-#if !defined(THREAD_SANITIZER)
- return 0;
-#else
- // ThreadSanitizer bloats the stack heavily. Evidence has been that the
- // default stack size isn't enough for some browser tests.
- return 2 * (1 << 23); // 2 times 8192K (the default stack size on Linux).
-#endif
-}
-
-} // namespace base
diff --git a/base/threading/platform_thread_mac.mm b/base/threading/platform_thread_mac.mm
deleted file mode 100644
index 770b618..0000000
--- a/base/threading/platform_thread_mac.mm
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/threading/platform_thread.h"
-
-#import <Foundation/Foundation.h>
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-#include <mach/thread_policy.h>
-#include <stddef.h>
-#include <sys/resource.h>
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/mach_logging.h"
-#include "util/build_config.h"
-
-namespace base {
-
-namespace {
-NSString* const kThreadPriorityKey = @"CrThreadPriorityKey";
-} // namespace
-
-// If Cocoa is to be used on more than one thread, it must know that the
-// application is multithreaded. Since it's possible to enter Cocoa code
-// from threads created by pthread_thread_create, Cocoa won't necessarily
-// be aware that the application is multithreaded. Spawning an NSThread is
-// enough to get Cocoa to set up for multithreaded operation, so this is done
-// if necessary before pthread_thread_create spawns any threads.
-//
-// http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/chapter_4_section_4.html
-void InitThreading() {
- static BOOL multithreaded = [NSThread isMultiThreaded];
- if (!multithreaded) {
- // +[NSObject class] is idempotent.
- [NSThread detachNewThreadSelector:@selector(class)
- toTarget:[NSObject class]
- withObject:nil];
- multithreaded = YES;
-
- DCHECK([NSThread isMultiThreaded]);
- }
-}
-
-size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
-#if defined(OS_IOS)
- return 0;
-#else
- // The Mac OS X default for a pthread stack size is 512kB.
- // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses
- // DEFAULT_STACK_SIZE for this purpose.
- //
- // 512kB isn't quite generous enough for some deeply recursive threads that
- // otherwise request the default stack size by specifying 0. Here, adopt
- // glibc's behavior as on Linux, which is to use the current stack size
- // limit (ulimit -s) as the default stack size. See
- // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To
- // avoid setting the limit below the Mac OS X default or the minimum usable
- // stack size, these values are also considered. If any of these values
- // can't be determined, or if stack size is unlimited (ulimit -s unlimited),
- // stack_size is left at 0 to get the system default.
- //
- // Mac OS X normally only applies ulimit -s to the main thread stack. On
- // contemporary OS X and Linux systems alike, this value is generally 8MB
- // or in that neighborhood.
- size_t default_stack_size = 0;
- struct rlimit stack_rlimit;
- if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 &&
- getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 &&
- stack_rlimit.rlim_cur != RLIM_INFINITY) {
- default_stack_size = std::max(
- std::max(default_stack_size, static_cast<size_t>(PTHREAD_STACK_MIN)),
- static_cast<size_t>(stack_rlimit.rlim_cur));
- }
- return default_stack_size;
-#endif
-}
-
-void TerminateOnThread() {}
-
-} // namespace base
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
deleted file mode 100644
index 42fbce5..0000000
--- a/base/threading/platform_thread_posix.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/threading/platform_thread.h"
-
-#include <errno.h>
-#include <pthread.h>
-#include <sched.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <memory>
-
-#include "base/logging.h"
-#include "util/build_config.h"
-
-#if defined(OS_LINUX)
-#include <sys/syscall.h>
-#endif
-
-#include <sys/resource.h>
-
-namespace base {
-
-void InitThreading();
-void TerminateOnThread();
-size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes);
-
-namespace {
-
-struct ThreadParams {
- ThreadParams() : delegate(nullptr), joinable(false) {}
-
- PlatformThread::Delegate* delegate;
- bool joinable;
-};
-
-void* ThreadFunc(void* params) {
- PlatformThread::Delegate* delegate = nullptr;
-
- {
- std::unique_ptr<ThreadParams> thread_params(
- static_cast<ThreadParams*>(params));
-
- delegate = thread_params->delegate;
- }
-
- delegate->ThreadMain();
-
- base::TerminateOnThread();
- return nullptr;
-}
-
-bool CreateThread(size_t stack_size,
- bool joinable,
- PlatformThread::Delegate* delegate,
- PlatformThreadHandle* thread_handle) {
- DCHECK(thread_handle);
- base::InitThreading();
-
- pthread_attr_t attributes;
- pthread_attr_init(&attributes);
-
- // Pthreads are joinable by default, so only specify the detached
- // attribute if the thread should be non-joinable.
- if (!joinable)
- pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
-
- // Get a better default if available.
- if (stack_size == 0)
- stack_size = base::GetDefaultThreadStackSize(attributes);
-
- if (stack_size > 0)
- pthread_attr_setstacksize(&attributes, stack_size);
-
- std::unique_ptr<ThreadParams> params(new ThreadParams);
- params->delegate = delegate;
- params->joinable = joinable;
-
- pthread_t handle;
- int err = pthread_create(&handle, &attributes, ThreadFunc, params.get());
- bool success = !err;
- if (success) {
- // ThreadParams should be deleted on the created thread after used.
- ignore_result(params.release());
- } else {
- // Value of |handle| is undefined if pthread_create fails.
- handle = 0;
- errno = err;
- PLOG(ERROR) << "pthread_create";
- }
- *thread_handle = PlatformThreadHandle(handle);
-
- pthread_attr_destroy(&attributes);
-
- return success;
-}
-
-} // namespace
-
-// static
-PlatformThreadId PlatformThread::CurrentId() {
-// Pthreads doesn't have the concept of a thread ID, so we have to reach down
-// into the kernel.
-#if defined(OS_MACOSX)
- return pthread_mach_thread_np(pthread_self());
-#elif defined(OS_LINUX)
- return syscall(__NR_gettid);
-#else
-#error
-#endif
-}
-
-// static
-PlatformThreadRef PlatformThread::CurrentRef() {
- return PlatformThreadRef(pthread_self());
-}
-
-// static
-PlatformThreadHandle PlatformThread::CurrentHandle() {
- return PlatformThreadHandle(pthread_self());
-}
-
-// static
-void PlatformThread::YieldCurrentThread() {
- sched_yield();
-}
-
-// static
-void PlatformThread::Sleep(TimeDelta duration) {
- struct timespec sleep_time, remaining;
-
- // Break the duration into seconds and nanoseconds.
- // NOTE: TimeDelta's microseconds are int64s while timespec's
- // nanoseconds are longs, so this unpacking must prevent overflow.
- sleep_time.tv_sec = duration.InSeconds();
- duration -= TimeDelta::FromSeconds(sleep_time.tv_sec);
- sleep_time.tv_nsec = duration.InMicroseconds() * 1000; // nanoseconds
-
- while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR)
- sleep_time = remaining;
-}
-
-// static
-bool PlatformThread::Create(size_t stack_size,
- Delegate* delegate,
- PlatformThreadHandle* thread_handle) {
- return CreateThread(stack_size, true /* joinable thread */, delegate,
- thread_handle);
-}
-
-// static
-bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
- PlatformThreadHandle unused;
-
- bool result = CreateThread(stack_size, false /* non-joinable thread */,
- delegate, &unused);
- return result;
-}
-
-// static
-void PlatformThread::Join(PlatformThreadHandle thread_handle) {
- CHECK_EQ(0, pthread_join(thread_handle.platform_handle(), nullptr));
-}
-
-// static
-void PlatformThread::Detach(PlatformThreadHandle thread_handle) {
- CHECK_EQ(0, pthread_detach(thread_handle.platform_handle()));
-}
-
-} // namespace base
diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc
deleted file mode 100644
index 349a6cf..0000000
--- a/base/threading/platform_thread_win.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/threading/platform_thread.h"
-
-#include <stddef.h>
-
-#include "base/logging.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/win/scoped_handle.h"
-
-#include <windows.h>
-
-namespace base {
-
-namespace {
-
-// The information on how to set the thread name comes from
-// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx
-const DWORD kVCThreadNameException = 0x406D1388;
-
-typedef struct tagTHREADNAME_INFO {
- DWORD dwType; // Must be 0x1000.
- LPCSTR szName; // Pointer to name (in user addr space).
- DWORD dwThreadID; // Thread ID (-1=caller thread).
- DWORD dwFlags; // Reserved for future use, must be zero.
-} THREADNAME_INFO;
-
-// The SetThreadDescription API was brought in version 1607 of Windows 10.
-typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
- PCWSTR lpThreadDescription);
-
-// This function has try handling, so it is separated out of its caller.
-void SetNameInternal(PlatformThreadId thread_id, const char* name) {
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = name;
- info.dwThreadID = thread_id;
- info.dwFlags = 0;
-
- __try {
- RaiseException(kVCThreadNameException, 0, sizeof(info) / sizeof(DWORD),
- reinterpret_cast<DWORD_PTR*>(&info));
- } __except (EXCEPTION_CONTINUE_EXECUTION) {
- }
-}
-
-struct ThreadParams {
- PlatformThread::Delegate* delegate;
- bool joinable;
-};
-
-DWORD __stdcall ThreadFunc(void* params) {
- ThreadParams* thread_params = static_cast<ThreadParams*>(params);
- PlatformThread::Delegate* delegate = thread_params->delegate;
-
- // Retrieve a copy of the thread handle to use as the key in the
- // thread name mapping.
- PlatformThreadHandle::Handle platform_handle;
- BOOL did_dup = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
- GetCurrentProcess(), &platform_handle, 0,
- FALSE, DUPLICATE_SAME_ACCESS);
-
- win::ScopedHandle scoped_platform_handle;
-
- if (did_dup) {
- scoped_platform_handle.Set(platform_handle);
- }
-
- delete thread_params;
- delegate->ThreadMain();
-
- return 0;
-}
-
-// CreateThreadInternal() matches PlatformThread::CreateWithPriority(), except
-// that |out_thread_handle| may be nullptr, in which case a non-joinable thread
-// is created.
-bool CreateThreadInternal(size_t stack_size,
- PlatformThread::Delegate* delegate,
- PlatformThreadHandle* out_thread_handle) {
- unsigned int flags = 0;
- if (stack_size > 0) {
- flags = STACK_SIZE_PARAM_IS_A_RESERVATION;
- }
-
- ThreadParams* params = new ThreadParams;
- params->delegate = delegate;
- params->joinable = out_thread_handle != nullptr;
-
- void* thread_handle;
- {
- // Using CreateThread here vs _beginthreadex makes thread creation a bit
- // faster and doesn't require the loader lock to be available. Our code
- // will have to work running on CreateThread() threads anyway, since we run
- // code on the Windows thread pool, etc. For some background on the
- // difference:
- // http://www.microsoft.com/msj/1099/win32/win321099.aspx
- thread_handle =
- ::CreateThread(nullptr, stack_size, ThreadFunc, params, flags, nullptr);
- }
-
- if (!thread_handle) {
- delete params;
- return false;
- }
-
- if (out_thread_handle)
- *out_thread_handle = PlatformThreadHandle(thread_handle);
- else
- CloseHandle(thread_handle);
- return true;
-}
-
-} // namespace
-
-// static
-PlatformThreadId PlatformThread::CurrentId() {
- return ::GetCurrentThreadId();
-}
-
-// static
-PlatformThreadRef PlatformThread::CurrentRef() {
- return PlatformThreadRef(::GetCurrentThreadId());
-}
-
-// static
-PlatformThreadHandle PlatformThread::CurrentHandle() {
- return PlatformThreadHandle(::GetCurrentThread());
-}
-
-// static
-void PlatformThread::YieldCurrentThread() {
- ::Sleep(0);
-}
-
-// static
-void PlatformThread::Sleep(TimeDelta duration) {
- // When measured with a high resolution clock, Sleep() sometimes returns much
- // too early. We may need to call it repeatedly to get the desired duration.
- TimeTicks end = TimeTicks::Now() + duration;
- for (TimeTicks now = TimeTicks::Now(); now < end; now = TimeTicks::Now())
- ::Sleep(static_cast<DWORD>((end - now).InMillisecondsRoundedUp()));
-}
-
-// static
-bool PlatformThread::Create(size_t stack_size,
- Delegate* delegate,
- PlatformThreadHandle* thread_handle) {
- DCHECK(thread_handle);
- return CreateThreadInternal(stack_size, delegate, thread_handle);
-}
-
-// static
-bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
- return CreateThreadInternal(stack_size, delegate, nullptr /* non-joinable */
- );
-}
-
-// static
-void PlatformThread::Join(PlatformThreadHandle thread_handle) {
- DCHECK(thread_handle.platform_handle());
- // TODO(willchan): Enable this check once I can get it to work for Windows
- // shutdown.
- // Joining another thread may block the current thread for a long time, since
- // the thread referred to by |thread_handle| may still be running long-lived /
- // blocking tasks.
- // AssertBlockingAllowed();
-
- DWORD thread_id = 0;
- thread_id = ::GetThreadId(thread_handle.platform_handle());
- DWORD last_error = 0;
- if (!thread_id)
- last_error = ::GetLastError();
-
- // Wait for the thread to exit. It should already have terminated but make
- // sure this assumption is valid.
- CHECK_EQ(WAIT_OBJECT_0,
- WaitForSingleObject(thread_handle.platform_handle(), INFINITE));
- CloseHandle(thread_handle.platform_handle());
-}
-
-// static
-void PlatformThread::Detach(PlatformThreadHandle thread_handle) {
- CloseHandle(thread_handle.platform_handle());
-}
-
-} // namespace base
diff --git a/base/time/clock.cc b/base/time/clock.cc
deleted file mode 100644
index 9e3f271..0000000
--- a/base/time/clock.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/time/clock.h"
-
-namespace base {
-
-Clock::~Clock() = default;
-
-} // namespace base
diff --git a/base/time/clock.h b/base/time/clock.h
deleted file mode 100644
index 8f3a27f..0000000
--- a/base/time/clock.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_TIME_CLOCK_H_
-#define BASE_TIME_CLOCK_H_
-
-#include "base/time/time.h"
-
-namespace base {
-
-// A Clock is an interface for objects that vend Times. It is
-// intended to be able to test the behavior of classes with respect to
-// time.
-//
-// See DefaultClock (base/time/default_clock.h) for the default
-// implementation that simply uses Time::Now().
-//
-// (An implementation that uses Time::SystemTime() should be added as
-// needed.)
-//
-// See SimpleTestClock (base/test/simple_test_clock.h) for a simple
-// test implementation.
-//
-// See TickClock (base/time/tick_clock.h) for the equivalent interface for
-// TimeTicks.
-class Clock {
- public:
- virtual ~Clock();
-
- // Now() must be safe to call from any thread. The caller cannot
- // make any ordering assumptions about the returned Time. For
- // example, the system clock may change to an earlier time.
- virtual Time Now() const = 0;
-};
-
-} // namespace base
-
-#endif // BASE_TIME_CLOCK_H_
diff --git a/base/time/time.cc b/base/time/time.cc
deleted file mode 100644
index 13b2343..0000000
--- a/base/time/time.cc
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/time/time.h"
-
-#include <cmath>
-#include <ios>
-#include <limits>
-#include <ostream>
-#include <sstream>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/no_destructor.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/time_override.h"
-#include "util/build_config.h"
-
-namespace base {
-
-namespace internal {
-
-TimeNowFunction g_time_now_function = &subtle::TimeNowIgnoringOverride;
-
-TimeNowFunction g_time_now_from_system_time_function =
- &subtle::TimeNowFromSystemTimeIgnoringOverride;
-
-TimeTicksNowFunction g_time_ticks_now_function =
- &subtle::TimeTicksNowIgnoringOverride;
-
-ThreadTicksNowFunction g_thread_ticks_now_function =
- &subtle::ThreadTicksNowIgnoringOverride;
-
-} // namespace internal
-
-// TimeDelta ------------------------------------------------------------------
-
-int TimeDelta::InDays() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<int>::max();
- }
- return static_cast<int>(delta_ / Time::kMicrosecondsPerDay);
-}
-
-int TimeDelta::InHours() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<int>::max();
- }
- return static_cast<int>(delta_ / Time::kMicrosecondsPerHour);
-}
-
-int TimeDelta::InMinutes() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<int>::max();
- }
- return static_cast<int>(delta_ / Time::kMicrosecondsPerMinute);
-}
-
-double TimeDelta::InSecondsF() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<double>::infinity();
- }
- return static_cast<double>(delta_) / Time::kMicrosecondsPerSecond;
-}
-
-int64_t TimeDelta::InSeconds() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<int64_t>::max();
- }
- return delta_ / Time::kMicrosecondsPerSecond;
-}
-
-double TimeDelta::InMillisecondsF() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<double>::infinity();
- }
- return static_cast<double>(delta_) / Time::kMicrosecondsPerMillisecond;
-}
-
-int64_t TimeDelta::InMilliseconds() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<int64_t>::max();
- }
- return delta_ / Time::kMicrosecondsPerMillisecond;
-}
-
-int64_t TimeDelta::InMillisecondsRoundedUp() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<int64_t>::max();
- }
- return (delta_ + Time::kMicrosecondsPerMillisecond - 1) /
- Time::kMicrosecondsPerMillisecond;
-}
-
-int64_t TimeDelta::InMicroseconds() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<int64_t>::max();
- }
- return delta_;
-}
-
-double TimeDelta::InMicrosecondsF() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<double>::infinity();
- }
- return static_cast<double>(delta_);
-}
-
-int64_t TimeDelta::InNanoseconds() const {
- if (is_max()) {
- // Preserve max to prevent overflow.
- return std::numeric_limits<int64_t>::max();
- }
- return delta_ * Time::kNanosecondsPerMicrosecond;
-}
-
-namespace time_internal {
-
-int64_t SaturatedAdd(TimeDelta delta, int64_t value) {
- CheckedNumeric<int64_t> rv(delta.delta_);
- rv += value;
- if (rv.IsValid())
- return rv.ValueOrDie();
- // Positive RHS overflows. Negative RHS underflows.
- if (value < 0)
- return std::numeric_limits<int64_t>::min();
- return std::numeric_limits<int64_t>::max();
-}
-
-int64_t SaturatedSub(TimeDelta delta, int64_t value) {
- CheckedNumeric<int64_t> rv(delta.delta_);
- rv -= value;
- if (rv.IsValid())
- return rv.ValueOrDie();
- // Negative RHS overflows. Positive RHS underflows.
- if (value < 0)
- return std::numeric_limits<int64_t>::max();
- return std::numeric_limits<int64_t>::min();
-}
-
-} // namespace time_internal
-
-std::ostream& operator<<(std::ostream& os, TimeDelta time_delta) {
- return os << time_delta.InSecondsF() << " s";
-}
-
-// Time -----------------------------------------------------------------------
-
-// static
-Time Time::Now() {
- return internal::g_time_now_function();
-}
-
-// static
-Time Time::NowFromSystemTime() {
- // Just use g_time_now_function because it returns the system time.
- return internal::g_time_now_from_system_time_function();
-}
-
-// static
-Time Time::FromDeltaSinceWindowsEpoch(TimeDelta delta) {
- return Time(delta.InMicroseconds());
-}
-
-TimeDelta Time::ToDeltaSinceWindowsEpoch() const {
- return TimeDelta::FromMicroseconds(us_);
-}
-
-// static
-Time Time::FromTimeT(time_t tt) {
- if (tt == 0)
- return Time(); // Preserve 0 so we can tell it doesn't exist.
- if (tt == std::numeric_limits<time_t>::max())
- return Max();
- return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSeconds(tt);
-}
-
-time_t Time::ToTimeT() const {
- if (is_null())
- return 0; // Preserve 0 so we can tell it doesn't exist.
- if (is_max()) {
- // Preserve max without offset to prevent overflow.
- return std::numeric_limits<time_t>::max();
- }
- if (std::numeric_limits<int64_t>::max() - kTimeTToMicrosecondsOffset <= us_) {
- DLOG(WARNING) << "Overflow when converting base::Time with internal "
- << "value " << us_ << " to time_t.";
- return std::numeric_limits<time_t>::max();
- }
- return (us_ - kTimeTToMicrosecondsOffset) / kMicrosecondsPerSecond;
-}
-
-// static
-Time Time::FromDoubleT(double dt) {
- if (dt == 0 || std::isnan(dt))
- return Time(); // Preserve 0 so we can tell it doesn't exist.
- return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSecondsD(dt);
-}
-
-double Time::ToDoubleT() const {
- if (is_null())
- return 0; // Preserve 0 so we can tell it doesn't exist.
- if (is_max()) {
- // Preserve max without offset to prevent overflow.
- return std::numeric_limits<double>::infinity();
- }
- return (static_cast<double>(us_ - kTimeTToMicrosecondsOffset) /
- static_cast<double>(kMicrosecondsPerSecond));
-}
-
-#if defined(OS_POSIX)
-// static
-Time Time::FromTimeSpec(const timespec& ts) {
- return FromDoubleT(ts.tv_sec + static_cast<double>(ts.tv_nsec) /
- base::Time::kNanosecondsPerSecond);
-}
-#endif
-
-// static
-Time Time::FromJsTime(double ms_since_epoch) {
- // The epoch is a valid time, so this constructor doesn't interpret
- // 0 as the null time.
- return Time(kTimeTToMicrosecondsOffset) +
- TimeDelta::FromMillisecondsD(ms_since_epoch);
-}
-
-double Time::ToJsTime() const {
- if (is_null()) {
- // Preserve 0 so the invalid result doesn't depend on the platform.
- return 0;
- }
- if (is_max()) {
- // Preserve max without offset to prevent overflow.
- return std::numeric_limits<double>::infinity();
- }
- return (static_cast<double>(us_ - kTimeTToMicrosecondsOffset) /
- kMicrosecondsPerMillisecond);
-}
-
-Time Time::FromJavaTime(int64_t ms_since_epoch) {
- return base::Time::UnixEpoch() +
- base::TimeDelta::FromMilliseconds(ms_since_epoch);
-}
-
-int64_t Time::ToJavaTime() const {
- if (is_null()) {
- // Preserve 0 so the invalid result doesn't depend on the platform.
- return 0;
- }
- if (is_max()) {
- // Preserve max without offset to prevent overflow.
- return std::numeric_limits<int64_t>::max();
- }
- return ((us_ - kTimeTToMicrosecondsOffset) / kMicrosecondsPerMillisecond);
-}
-
-// static
-Time Time::UnixEpoch() {
- Time time;
- time.us_ = kTimeTToMicrosecondsOffset;
- return time;
-}
-
-// TimeTicks ------------------------------------------------------------------
-
-// static
-TimeTicks TimeTicks::Now() {
- return internal::g_time_ticks_now_function();
-}
-
-// static
-TimeTicks TimeTicks::UnixEpoch() {
- static const base::NoDestructor<base::TimeTicks> epoch([]() {
- return subtle::TimeTicksNowIgnoringOverride() -
- (subtle::TimeNowIgnoringOverride() - Time::UnixEpoch());
- }());
- return *epoch;
-}
-
-TimeTicks TimeTicks::SnappedToNextTick(TimeTicks tick_phase,
- TimeDelta tick_interval) const {
- // |interval_offset| is the offset from |this| to the next multiple of
- // |tick_interval| after |tick_phase|, possibly negative if in the past.
- TimeDelta interval_offset = (tick_phase - *this) % tick_interval;
- // If |this| is exactly on the interval (i.e. offset==0), don't adjust.
- // Otherwise, if |tick_phase| was in the past, adjust forward to the next
- // tick after |this|.
- if (!interval_offset.is_zero() && tick_phase < *this)
- interval_offset += tick_interval;
- return *this + interval_offset;
-}
-
-std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks) {
- // This function formats a TimeTicks object as "bogo-microseconds".
- // The origin and granularity of the count are platform-specific, and may very
- // from run to run. Although bogo-microseconds usually roughly correspond to
- // real microseconds, the only real guarantee is that the number never goes
- // down during a single run.
- const TimeDelta as_time_delta = time_ticks - TimeTicks();
- return os << as_time_delta.InMicroseconds() << " bogo-microseconds";
-}
-
-// ThreadTicks ----------------------------------------------------------------
-
-// static
-ThreadTicks ThreadTicks::Now() {
- return internal::g_thread_ticks_now_function();
-}
-
-std::ostream& operator<<(std::ostream& os, ThreadTicks thread_ticks) {
- const TimeDelta as_time_delta = thread_ticks - ThreadTicks();
- return os << as_time_delta.InMicroseconds() << " bogo-thread-microseconds";
-}
-
-// Time::Exploded -------------------------------------------------------------
-
-inline bool is_in_range(int value, int lo, int hi) {
- return lo <= value && value <= hi;
-}
-
-bool Time::Exploded::HasValidValues() const {
- return is_in_range(month, 1, 12) && is_in_range(day_of_week, 0, 6) &&
- is_in_range(day_of_month, 1, 31) && is_in_range(hour, 0, 23) &&
- is_in_range(minute, 0, 59) && is_in_range(second, 0, 60) &&
- is_in_range(millisecond, 0, 999);
-}
-
-} // namespace base
diff --git a/base/time/time.h b/base/time/time.h
deleted file mode 100644
index 47d7536..0000000
--- a/base/time/time.h
+++ /dev/null
@@ -1,871 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Time represents an absolute point in coordinated universal time (UTC),
-// internally represented as microseconds (s/1,000,000) since the Windows epoch
-// (1601-01-01 00:00:00 UTC). System-dependent clock interface routines are
-// defined in time_PLATFORM.cc. Note that values for Time may skew and jump
-// around as the operating system makes adjustments to synchronize (e.g., with
-// NTP servers). Thus, client code that uses the Time class must account for
-// this.
-//
-// TimeDelta represents a duration of time, internally represented in
-// microseconds.
-//
-// TimeTicks and ThreadTicks represent an abstract time that is most of the time
-// incrementing, for use in measuring time durations. Internally, they are
-// represented in microseconds. They cannot be converted to a human-readable
-// time, but are guaranteed not to decrease (unlike the Time class). Note that
-// TimeTicks may "stand still" (e.g., if the computer is suspended), and
-// ThreadTicks will "stand still" whenever the thread has been de-scheduled by
-// the operating system.
-//
-// All time classes are copyable, assignable, and occupy 64-bits per instance.
-// As a result, prefer passing them by value:
-// void MyFunction(TimeDelta arg);
-// If circumstances require, you may also pass by const reference:
-// void MyFunction(const TimeDelta& arg); // Not preferred.
-//
-// Definitions of operator<< are provided to make these types work with
-// DCHECK_EQ() and other log macros. For human-readable formatting, see
-// "base/i18n/time_formatting.h".
-//
-// So many choices! Which time class should you use? Examples:
-//
-// Time: Interpreting the wall-clock time provided by a remote system.
-// Detecting whether cached resources have expired. Providing the
-// user with a display of the current date and time. Determining
-// the amount of time between events across re-boots of the
-// machine.
-//
-// TimeTicks: Tracking the amount of time a task runs. Executing delayed
-// tasks at the right time. Computing presentation timestamps.
-// Synchronizing audio and video using TimeTicks as a common
-// reference clock (lip-sync). Measuring network round-trip
-// latency.
-//
-// ThreadTicks: Benchmarking how long the current thread has been doing actual
-// work.
-
-#ifndef BASE_TIME_TIME_H_
-#define BASE_TIME_TIME_H_
-
-#include <stdint.h>
-#include <time.h>
-
-#include <iosfwd>
-#include <limits>
-
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/numerics/safe_math.h"
-#include "util/build_config.h"
-
-#if defined(OS_MACOSX)
-#include <CoreFoundation/CoreFoundation.h>
-// Avoid Mac system header macro leak.
-#undef TYPE_BOOL
-#endif
-
-#if defined(OS_POSIX)
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
-#if defined(OS_WIN)
-#include "base/gtest_prod_util.h"
-#include "base/win/windows_types.h"
-#endif
-
-namespace base {
-
-class PlatformThreadHandle;
-class TimeDelta;
-
-// The functions in the time_internal namespace are meant to be used only by the
-// time classes and functions. Please use the math operators defined in the
-// time classes instead.
-namespace time_internal {
-
-// Add or subtract |value| from a TimeDelta. The int64_t argument and return
-// value are in terms of a microsecond timebase.
-int64_t SaturatedAdd(TimeDelta delta, int64_t value);
-int64_t SaturatedSub(TimeDelta delta, int64_t value);
-
-} // namespace time_internal
-
-// TimeDelta ------------------------------------------------------------------
-
-class TimeDelta {
- public:
- constexpr TimeDelta() : delta_(0) {}
-
- // Converts units of time to TimeDeltas.
- static constexpr TimeDelta FromDays(int days);
- static constexpr TimeDelta FromHours(int hours);
- static constexpr TimeDelta FromMinutes(int minutes);
- static constexpr TimeDelta FromSeconds(int64_t secs);
- static constexpr TimeDelta FromMilliseconds(int64_t ms);
- static constexpr TimeDelta FromMicroseconds(int64_t us);
- static constexpr TimeDelta FromNanoseconds(int64_t ns);
- static constexpr TimeDelta FromSecondsD(double secs);
- static constexpr TimeDelta FromMillisecondsD(double ms);
- static constexpr TimeDelta FromMicrosecondsD(double us);
- static constexpr TimeDelta FromNanosecondsD(double ns);
-#if defined(OS_WIN)
- static TimeDelta FromQPCValue(LONGLONG qpc_value);
- static TimeDelta FromFileTime(FILETIME ft);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
- static TimeDelta FromTimeSpec(const timespec& ts);
-#endif
-
- // Converts an integer value representing TimeDelta to a class. This is used
- // when deserializing a |TimeDelta| structure, using a value known to be
- // compatible. It is not provided as a constructor because the integer type
- // may be unclear from the perspective of a caller.
- //
- // DEPRECATED - Do not use in new code. http://crbug.com/634507
- static constexpr TimeDelta FromInternalValue(int64_t delta) {
- return TimeDelta(delta);
- }
-
- // Returns the maximum time delta, which should be greater than any reasonable
- // time delta we might compare it to. Adding or subtracting the maximum time
- // delta to a time or another time delta has an undefined result.
- static constexpr TimeDelta Max();
-
- // Returns the minimum time delta, which should be less than than any
- // reasonable time delta we might compare it to. Adding or subtracting the
- // minimum time delta to a time or another time delta has an undefined result.
- static constexpr TimeDelta Min();
-
- // Returns the internal numeric value of the TimeDelta object. Please don't
- // use this and do arithmetic on it, as it is more error prone than using the
- // provided operators.
- // For serializing, use FromInternalValue to reconstitute.
- //
- // DEPRECATED - Do not use in new code. http://crbug.com/634507
- constexpr int64_t ToInternalValue() const { return delta_; }
-
- // Returns the magnitude (absolute value) of this TimeDelta.
- constexpr TimeDelta magnitude() const {
- // Some toolchains provide an incomplete C++11 implementation and lack an
- // int64_t overload for std::abs(). The following is a simple branchless
- // implementation:
- const int64_t mask = delta_ >> (sizeof(delta_) * 8 - 1);
- return TimeDelta((delta_ + mask) ^ mask);
- }
-
- // Returns true if the time delta is zero.
- constexpr bool is_zero() const { return delta_ == 0; }
-
- // Returns true if the time delta is the maximum/minimum time delta.
- constexpr bool is_max() const {
- return delta_ == std::numeric_limits<int64_t>::max();
- }
- constexpr bool is_min() const {
- return delta_ == std::numeric_limits<int64_t>::min();
- }
-
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
- struct timespec ToTimeSpec() const;
-#endif
-
- // Returns the time delta in some unit. The F versions return a floating
- // point value, the "regular" versions return a rounded-down value.
- //
- // InMillisecondsRoundedUp() instead returns an integer that is rounded up
- // to the next full millisecond.
- int InDays() const;
- int InHours() const;
- int InMinutes() const;
- double InSecondsF() const;
- int64_t InSeconds() const;
- double InMillisecondsF() const;
- int64_t InMilliseconds() const;
- int64_t InMillisecondsRoundedUp() const;
- int64_t InMicroseconds() const;
- double InMicrosecondsF() const;
- int64_t InNanoseconds() const;
-
- constexpr TimeDelta& operator=(TimeDelta other) {
- delta_ = other.delta_;
- return *this;
- }
-
- // Computations with other deltas. Can easily be made constexpr with C++17 but
- // hard to do until then per limitations around
- // __builtin_(add|sub)_overflow in safe_math_clang_gcc_impl.h :
- // https://chromium-review.googlesource.com/c/chromium/src/+/873352#message-59594ab70827795a67e0780404adf37b4b6c2f14
- TimeDelta operator+(TimeDelta other) const {
- return TimeDelta(time_internal::SaturatedAdd(*this, other.delta_));
- }
- TimeDelta operator-(TimeDelta other) const {
- return TimeDelta(time_internal::SaturatedSub(*this, other.delta_));
- }
-
- TimeDelta& operator+=(TimeDelta other) { return *this = (*this + other); }
- TimeDelta& operator-=(TimeDelta other) { return *this = (*this - other); }
- constexpr TimeDelta operator-() const { return TimeDelta(-delta_); }
-
- // Computations with numeric types. operator*() isn't constexpr because of a
- // limitation around __builtin_mul_overflow (but operator/(1.0/a) works for
- // |a|'s of "reasonable" size -- i.e. that don't risk overflow).
- template <typename T>
- TimeDelta operator*(T a) const {
- CheckedNumeric<int64_t> rv(delta_);
- rv *= a;
- if (rv.IsValid())
- return TimeDelta(rv.ValueOrDie());
- // Matched sign overflows. Mismatched sign underflows.
- if ((delta_ < 0) ^ (a < 0))
- return TimeDelta(std::numeric_limits<int64_t>::min());
- return TimeDelta(std::numeric_limits<int64_t>::max());
- }
- template <typename T>
- constexpr TimeDelta operator/(T a) const {
- CheckedNumeric<int64_t> rv(delta_);
- rv /= a;
- if (rv.IsValid())
- return TimeDelta(rv.ValueOrDie());
- // Matched sign overflows. Mismatched sign underflows.
- // Special case to catch divide by zero.
- if ((delta_ < 0) ^ (a <= 0))
- return TimeDelta(std::numeric_limits<int64_t>::min());
- return TimeDelta(std::numeric_limits<int64_t>::max());
- }
- template <typename T>
- TimeDelta& operator*=(T a) {
- return *this = (*this * a);
- }
- template <typename T>
- constexpr TimeDelta& operator/=(T a) {
- return *this = (*this / a);
- }
-
- constexpr int64_t operator/(TimeDelta a) const { return delta_ / a.delta_; }
- constexpr TimeDelta operator%(TimeDelta a) const {
- return TimeDelta(delta_ % a.delta_);
- }
-
- // Comparison operators.
- constexpr bool operator==(TimeDelta other) const {
- return delta_ == other.delta_;
- }
- constexpr bool operator!=(TimeDelta other) const {
- return delta_ != other.delta_;
- }
- constexpr bool operator<(TimeDelta other) const {
- return delta_ < other.delta_;
- }
- constexpr bool operator<=(TimeDelta other) const {
- return delta_ <= other.delta_;
- }
- constexpr bool operator>(TimeDelta other) const {
- return delta_ > other.delta_;
- }
- constexpr bool operator>=(TimeDelta other) const {
- return delta_ >= other.delta_;
- }
-
-#if defined(OS_WIN)
- // This works around crbug.com/635974
- constexpr TimeDelta(const TimeDelta& other) : delta_(other.delta_) {}
-#endif
-
- private:
- friend int64_t time_internal::SaturatedAdd(TimeDelta delta, int64_t value);
- friend int64_t time_internal::SaturatedSub(TimeDelta delta, int64_t value);
-
- // Constructs a delta given the duration in microseconds. This is private
- // to avoid confusion by callers with an integer constructor. Use
- // FromSeconds, FromMilliseconds, etc. instead.
- constexpr explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {}
-
- // Private method to build a delta from a double.
- static constexpr TimeDelta FromDouble(double value);
-
- // Private method to build a delta from the product of a user-provided value
- // and a known-positive value.
- static constexpr TimeDelta FromProduct(int64_t value, int64_t positive_value);
-
- // Delta in microseconds.
- int64_t delta_;
-};
-
-template <typename T>
-TimeDelta operator*(T a, TimeDelta td) {
- return td * a;
-}
-
-// For logging use only.
-std::ostream& operator<<(std::ostream& os, TimeDelta time_delta);
-
-// Do not reference the time_internal::TimeBase template class directly. Please
-// use one of the time subclasses instead, and only reference the public
-// TimeBase members via those classes.
-namespace time_internal {
-
-// TimeBase--------------------------------------------------------------------
-
-// Provides value storage and comparison/math operations common to all time
-// classes. Each subclass provides for strong type-checking to ensure
-// semantically meaningful comparison/math of time values from the same clock
-// source or timeline.
-template <class TimeClass>
-class TimeBase {
- public:
- static const int64_t kHoursPerDay = 24;
- static const int64_t kMillisecondsPerSecond = 1000;
- static const int64_t kMillisecondsPerDay =
- kMillisecondsPerSecond * 60 * 60 * kHoursPerDay;
- static const int64_t kMicrosecondsPerMillisecond = 1000;
- static const int64_t kMicrosecondsPerSecond =
- kMicrosecondsPerMillisecond * kMillisecondsPerSecond;
- static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
- static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
- static const int64_t kMicrosecondsPerDay =
- kMicrosecondsPerHour * kHoursPerDay;
- static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
- static const int64_t kNanosecondsPerMicrosecond = 1000;
- static const int64_t kNanosecondsPerSecond =
- kNanosecondsPerMicrosecond * kMicrosecondsPerSecond;
-
- // Returns true if this object has not been initialized.
- //
- // Warning: Be careful when writing code that performs math on time values,
- // since it's possible to produce a valid "zero" result that should not be
- // interpreted as a "null" value.
- bool is_null() const { return us_ == 0; }
-
- // Returns true if this object represents the maximum/minimum time.
- bool is_max() const { return us_ == std::numeric_limits<int64_t>::max(); }
- bool is_min() const { return us_ == std::numeric_limits<int64_t>::min(); }
-
- // Returns the maximum/minimum times, which should be greater/less than than
- // any reasonable time with which we might compare it.
- static TimeClass Max() {
- return TimeClass(std::numeric_limits<int64_t>::max());
- }
-
- static TimeClass Min() {
- return TimeClass(std::numeric_limits<int64_t>::min());
- }
-
- // For serializing only. Use FromInternalValue() to reconstitute. Please don't
- // use this and do arithmetic on it, as it is more error prone than using the
- // provided operators.
- //
- // DEPRECATED - Do not use in new code. For serializing Time values, prefer
- // Time::ToDeltaSinceWindowsEpoch().InMicroseconds(). http://crbug.com/634507
- int64_t ToInternalValue() const { return us_; }
-
- // The amount of time since the origin (or "zero") point. This is a syntactic
- // convenience to aid in code readability, mainly for debugging/testing use
- // cases.
- //
- // Warning: While the Time subclass has a fixed origin point, the origin for
- // the other subclasses can vary each time the application is restarted.
- TimeDelta since_origin() const { return TimeDelta::FromMicroseconds(us_); }
-
- TimeClass& operator=(TimeClass other) {
- us_ = other.us_;
- return *(static_cast<TimeClass*>(this));
- }
-
- // Compute the difference between two times.
- TimeDelta operator-(TimeClass other) const {
- return TimeDelta::FromMicroseconds(us_ - other.us_);
- }
-
- // Return a new time modified by some delta.
- TimeClass operator+(TimeDelta delta) const {
- return TimeClass(time_internal::SaturatedAdd(delta, us_));
- }
- TimeClass operator-(TimeDelta delta) const {
- return TimeClass(-time_internal::SaturatedSub(delta, us_));
- }
-
- // Modify by some time delta.
- TimeClass& operator+=(TimeDelta delta) {
- return static_cast<TimeClass&>(*this = (*this + delta));
- }
- TimeClass& operator-=(TimeDelta delta) {
- return static_cast<TimeClass&>(*this = (*this - delta));
- }
-
- // Comparison operators
- bool operator==(TimeClass other) const { return us_ == other.us_; }
- bool operator!=(TimeClass other) const { return us_ != other.us_; }
- bool operator<(TimeClass other) const { return us_ < other.us_; }
- bool operator<=(TimeClass other) const { return us_ <= other.us_; }
- bool operator>(TimeClass other) const { return us_ > other.us_; }
- bool operator>=(TimeClass other) const { return us_ >= other.us_; }
-
- protected:
- constexpr explicit TimeBase(int64_t us) : us_(us) {}
-
- // Time value in a microsecond timebase.
- int64_t us_;
-};
-
-} // namespace time_internal
-
-template <class TimeClass>
-inline TimeClass operator+(TimeDelta delta, TimeClass t) {
- return t + delta;
-}
-
-// Time -----------------------------------------------------------------------
-
-// Represents a wall clock time in UTC. Values are not guaranteed to be
-// monotonically non-decreasing and are subject to large amounts of skew.
-class Time : public time_internal::TimeBase<Time> {
- public:
- // Offset of UNIX epoch (1970-01-01 00:00:00 UTC) from Windows FILETIME epoch
- // (1601-01-01 00:00:00 UTC), in microseconds. This value is derived from the
- // following: ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the number
- // of leap year days between 1601 and 1970: (1970-1601)/4 excluding 1700,
- // 1800, and 1900.
- static constexpr int64_t kTimeTToMicrosecondsOffset =
- INT64_C(11644473600000000);
-
-#if defined(OS_WIN)
- // To avoid overflow in QPC to Microseconds calculations, since we multiply
- // by kMicrosecondsPerSecond, then the QPC value should not exceed
- // (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply.
- static constexpr int64_t kQPCOverflowThreshold = INT64_C(0x8637BD05AF7);
-#endif
-
-// kExplodedMinYear and kExplodedMaxYear define the platform-specific limits
-// for values passed to FromUTCExploded() and FromLocalExploded(). Those
-// functions will return false if passed values outside these limits. The limits
-// are inclusive, meaning that the API should support all dates within a given
-// limit year.
-#if defined(OS_WIN)
- static constexpr int kExplodedMinYear = 1601;
- static constexpr int kExplodedMaxYear = 30827;
-#elif defined(OS_MACOSX)
- static constexpr int kExplodedMinYear = 1902;
- static constexpr int kExplodedMaxYear = std::numeric_limits<int>::max();
-#else
- static constexpr int kExplodedMinYear =
- (sizeof(time_t) == 4 ? 1902 : std::numeric_limits<int>::min());
- static constexpr int kExplodedMaxYear =
- (sizeof(time_t) == 4 ? 2037 : std::numeric_limits<int>::max());
-#endif
-
- // Represents an exploded time that can be formatted nicely. This is kind of
- // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few
- // additions and changes to prevent errors.
- struct Exploded {
- int year; // Four digit year "2007"
- int month; // 1-based month (values 1 = January, etc.)
- int day_of_week; // 0-based day of week (0 = Sunday, etc.)
- int day_of_month; // 1-based day of month (1-31)
- int hour; // Hour within the current day (0-23)
- int minute; // Minute within the current hour (0-59)
- int second; // Second within the current minute (0-59 plus leap
- // seconds which may take it up to 60).
- int millisecond; // Milliseconds within the current second (0-999)
-
- // A cursory test for whether the data members are within their
- // respective ranges. A 'true' return value does not guarantee the
- // Exploded value can be successfully converted to a Time value.
- bool HasValidValues() const;
- };
-
- // Contains the NULL time. Use Time::Now() to get the current time.
- constexpr Time() : TimeBase(0) {}
-
- // Returns the time for epoch in Unix-like system (Jan 1, 1970).
- static Time UnixEpoch();
-
- // Returns the current time. Watch out, the system might adjust its clock
- // in which case time will actually go backwards. We don't guarantee that
- // times are increasing, or that two calls to Now() won't be the same.
- static Time Now();
-
- // Returns the current time. Same as Now() except that this function always
- // uses system time so that there are no discrepancies between the returned
- // time and system time even on virtual environments including our test bot.
- // For timing sensitive unittests, this function should be used.
- static Time NowFromSystemTime();
-
- // Converts to/from TimeDeltas relative to the Windows epoch (1601-01-01
- // 00:00:00 UTC). Prefer these methods for opaque serialization and
- // deserialization of time values, e.g.
- //
- // // Serialization:
- // base::Time last_updated = ...;
- // SaveToDatabase(last_updated.ToDeltaSinceWindowsEpoch().InMicroseconds());
- //
- // // Deserialization:
- // base::Time last_updated = base::Time::FromDeltaSinceWindowsEpoch(
- // base::TimeDelta::FromMicroseconds(LoadFromDatabase()));
- static Time FromDeltaSinceWindowsEpoch(TimeDelta delta);
- TimeDelta ToDeltaSinceWindowsEpoch() const;
-
- // Converts to/from time_t in UTC and a Time class.
- static Time FromTimeT(time_t tt);
- time_t ToTimeT() const;
-
- // Converts time to/from a double which is the number of seconds since epoch
- // (Jan 1, 1970). Webkit uses this format to represent time.
- // Because WebKit initializes double time value to 0 to indicate "not
- // initialized", we map it to empty Time object that also means "not
- // initialized".
- static Time FromDoubleT(double dt);
- double ToDoubleT() const;
-
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
- // Converts the timespec structure to time. MacOS X 10.8.3 (and tentatively,
- // earlier versions) will have the |ts|'s tv_nsec component zeroed out,
- // having a 1 second resolution, which agrees with
- // https://developer.apple.com/legacy/library/#technotes/tn/tn1150.html#HFSPlusDates.
- static Time FromTimeSpec(const timespec& ts);
-#endif
-
- // Converts to/from the Javascript convention for times, a number of
- // milliseconds since the epoch:
- // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/getTime.
- static Time FromJsTime(double ms_since_epoch);
- double ToJsTime() const;
-
- // Converts to/from Java convention for times, a number of milliseconds since
- // the epoch. Because the Java format has less resolution, converting to Java
- // time is a lossy operation.
- static Time FromJavaTime(int64_t ms_since_epoch);
- int64_t ToJavaTime() const;
-
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
- static Time FromTimeVal(struct timeval t);
- struct timeval ToTimeVal() const;
-#endif
-
-#if defined(OS_MACOSX)
- static Time FromCFAbsoluteTime(CFAbsoluteTime t);
- CFAbsoluteTime ToCFAbsoluteTime() const;
-#endif
-
-#if defined(OS_WIN)
- static Time FromFileTime(FILETIME ft);
- FILETIME ToFileTime() const;
-
- // The minimum time of a low resolution timer. This is basically a windows
- // constant of ~15.6ms. While it does vary on some older OS versions, we'll
- // treat it as static across all windows versions.
- static const int kMinLowResolutionThresholdMs = 16;
-
- // Enable or disable Windows high resolution timer.
- static void EnableHighResolutionTimer(bool enable);
-
- // Activates or deactivates the high resolution timer based on the |activate|
- // flag. If the HighResolutionTimer is not Enabled (see
- // EnableHighResolutionTimer), this function will return false. Otherwise
- // returns true. Each successful activate call must be paired with a
- // subsequent deactivate call.
- // All callers to activate the high resolution timer must eventually call
- // this function to deactivate the high resolution timer.
- static bool ActivateHighResolutionTimer(bool activate);
-
- // Returns true if the high resolution timer is both enabled and activated.
- // This is provided for testing only, and is not tracked in a thread-safe
- // way.
- static bool IsHighResolutionTimerInUse();
-
- // The following two functions are used to report the fraction of elapsed time
- // that the high resolution timer is activated.
- // ResetHighResolutionTimerUsage() resets the cumulative usage and starts the
- // measurement interval and GetHighResolutionTimerUsage() returns the
- // percentage of time since the reset that the high resolution timer was
- // activated.
- // ResetHighResolutionTimerUsage() must be called at least once before calling
- // GetHighResolutionTimerUsage(); otherwise the usage result would be
- // undefined.
- static void ResetHighResolutionTimerUsage();
- static double GetHighResolutionTimerUsage();
-#endif // defined(OS_WIN)
-
- // Converts an integer value representing Time to a class. This may be used
- // when deserializing a |Time| structure, using a value known to be
- // compatible. It is not provided as a constructor because the integer type
- // may be unclear from the perspective of a caller.
- //
- // DEPRECATED - Do not use in new code. For deserializing Time values, prefer
- // Time::FromDeltaSinceWindowsEpoch(). http://crbug.com/634507
- static constexpr Time FromInternalValue(int64_t us) { return Time(us); }
-
- private:
- friend class time_internal::TimeBase<Time>;
-
- constexpr explicit Time(int64_t us) : TimeBase(us) {}
-};
-
-// static
-constexpr TimeDelta TimeDelta::FromDays(int days) {
- return days == std::numeric_limits<int>::max()
- ? Max()
- : TimeDelta(days * Time::kMicrosecondsPerDay);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromHours(int hours) {
- return hours == std::numeric_limits<int>::max()
- ? Max()
- : TimeDelta(hours * Time::kMicrosecondsPerHour);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromMinutes(int minutes) {
- return minutes == std::numeric_limits<int>::max()
- ? Max()
- : TimeDelta(minutes * Time::kMicrosecondsPerMinute);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromSeconds(int64_t secs) {
- return FromProduct(secs, Time::kMicrosecondsPerSecond);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromMilliseconds(int64_t ms) {
- return FromProduct(ms, Time::kMicrosecondsPerMillisecond);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromMicroseconds(int64_t us) {
- return TimeDelta(us);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromNanoseconds(int64_t ns) {
- return TimeDelta(ns / Time::kNanosecondsPerMicrosecond);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromSecondsD(double secs) {
- return FromDouble(secs * Time::kMicrosecondsPerSecond);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromMillisecondsD(double ms) {
- return FromDouble(ms * Time::kMicrosecondsPerMillisecond);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromMicrosecondsD(double us) {
- return FromDouble(us);
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromNanosecondsD(double ns) {
- return FromDouble(ns / Time::kNanosecondsPerMicrosecond);
-}
-
-// static
-constexpr TimeDelta TimeDelta::Max() {
- return TimeDelta(std::numeric_limits<int64_t>::max());
-}
-
-// static
-constexpr TimeDelta TimeDelta::Min() {
- return TimeDelta(std::numeric_limits<int64_t>::min());
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromDouble(double value) {
- // TODO(crbug.com/612601): Use saturated_cast<int64_t>(value) once we sort out
- // the Min() behavior.
- return value > std::numeric_limits<int64_t>::max()
- ? Max()
- : value < std::numeric_limits<int64_t>::min()
- ? Min()
- : TimeDelta(static_cast<int64_t>(value));
-}
-
-// static
-constexpr TimeDelta TimeDelta::FromProduct(int64_t value,
- int64_t positive_value) {
- DCHECK(positive_value > 0);
- return value > std::numeric_limits<int64_t>::max() / positive_value
- ? Max()
- : value < std::numeric_limits<int64_t>::min() / positive_value
- ? Min()
- : TimeDelta(value * positive_value);
-}
-
-// For logging use only.
-std::ostream& operator<<(std::ostream& os, Time time);
-
-// TimeTicks ------------------------------------------------------------------
-
-// Represents monotonically non-decreasing clock time.
-class TimeTicks : public time_internal::TimeBase<TimeTicks> {
- public:
- // The underlying clock used to generate new TimeTicks.
- enum class Clock {
- FUCHSIA_ZX_CLOCK_MONOTONIC,
- LINUX_CLOCK_MONOTONIC,
- IOS_CF_ABSOLUTE_TIME_MINUS_KERN_BOOTTIME,
- MAC_MACH_ABSOLUTE_TIME,
- WIN_QPC,
- WIN_ROLLOVER_PROTECTED_TIME_GET_TIME
- };
-
- constexpr TimeTicks() : TimeBase(0) {}
-
- // Platform-dependent tick count representing "right now." When
- // IsHighResolution() returns false, the resolution of the clock could be
- // as coarse as ~15.6ms. Otherwise, the resolution should be no worse than one
- // microsecond.
- static TimeTicks Now();
-
- // Returns true if the high resolution clock is working on this system and
- // Now() will return high resolution values. Note that, on systems where the
- // high resolution clock works but is deemed inefficient, the low resolution
- // clock will be used instead.
- static bool IsHighResolution() WARN_UNUSED_RESULT;
-
- // Returns true if TimeTicks is consistent across processes, meaning that
- // timestamps taken on different processes can be safely compared with one
- // another. (Note that, even on platforms where this returns true, time values
- // from different threads that are within one tick of each other must be
- // considered to have an ambiguous ordering.)
- static bool IsConsistentAcrossProcesses() WARN_UNUSED_RESULT;
-
-#if defined(OS_WIN)
- // Translates an absolute QPC timestamp into a TimeTicks value. The returned
- // value has the same origin as Now(). Do NOT attempt to use this if
- // IsHighResolution() returns false.
- static TimeTicks FromQPCValue(LONGLONG qpc_value);
-#endif
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- static TimeTicks FromMachAbsoluteTime(uint64_t mach_absolute_time);
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
-
- // Get an estimate of the TimeTick value at the time of the UnixEpoch. Because
- // Time and TimeTicks respond differently to user-set time and NTP
- // adjustments, this number is only an estimate. Nevertheless, this can be
- // useful when you need to relate the value of TimeTicks to a real time and
- // date. Note: Upon first invocation, this function takes a snapshot of the
- // realtime clock to establish a reference point. This function will return
- // the same value for the duration of the application, but will be different
- // in future application runs.
- static TimeTicks UnixEpoch();
-
- // Returns |this| snapped to the next tick, given a |tick_phase| and
- // repeating |tick_interval| in both directions. |this| may be before,
- // after, or equal to the |tick_phase|.
- TimeTicks SnappedToNextTick(TimeTicks tick_phase,
- TimeDelta tick_interval) const;
-
- // Returns an enum indicating the underlying clock being used to generate
- // TimeTicks timestamps. This function should only be used for debugging and
- // logging purposes.
- static Clock GetClock();
-
- // Converts an integer value representing TimeTicks to a class. This may be
- // used when deserializing a |TimeTicks| structure, using a value known to be
- // compatible. It is not provided as a constructor because the integer type
- // may be unclear from the perspective of a caller.
- //
- // DEPRECATED - Do not use in new code. For deserializing TimeTicks values,
- // prefer TimeTicks + TimeDelta(). http://crbug.com/634507
- static constexpr TimeTicks FromInternalValue(int64_t us) {
- return TimeTicks(us);
- }
-
- private:
- friend class time_internal::TimeBase<TimeTicks>;
-
- // Please use Now() to create a new object. This is for internal use
- // and testing.
- constexpr explicit TimeTicks(int64_t us) : TimeBase(us) {}
-};
-
-// For logging use only.
-std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks);
-
-// ThreadTicks ----------------------------------------------------------------
-
-// Represents a clock, specific to a particular thread, than runs only while the
-// thread is running.
-class ThreadTicks : public time_internal::TimeBase<ThreadTicks> {
- public:
- ThreadTicks() : TimeBase(0) {}
-
- // Returns true if ThreadTicks::Now() is supported on this system.
- static bool IsSupported() WARN_UNUSED_RESULT {
-#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \
- (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_ANDROID) || \
- defined(OS_FUCHSIA) || defined(OS_WIN)
- return true;
-#else
- return false;
-#endif
- }
-
- // Waits until the initialization is completed. Needs to be guarded with a
- // call to IsSupported().
- static void WaitUntilInitialized() {
-#if defined(OS_WIN)
- WaitUntilInitializedWin();
-#endif
- }
-
- // Returns thread-specific CPU-time on systems that support this feature.
- // Needs to be guarded with a call to IsSupported(). Use this timer
- // to (approximately) measure how much time the calling thread spent doing
- // actual work vs. being de-scheduled. May return bogus results if the thread
- // migrates to another CPU between two calls. Returns an empty ThreadTicks
- // object until the initialization is completed. If a clock reading is
- // absolutely needed, call WaitUntilInitialized() before this method.
- static ThreadTicks Now();
-
-#if defined(OS_WIN)
- // Similar to Now() above except this returns thread-specific CPU time for an
- // arbitrary thread. All comments for Now() method above apply apply to this
- // method as well.
- static ThreadTicks GetForThread(const PlatformThreadHandle& thread_handle);
-#endif
-
- // Converts an integer value representing ThreadTicks to a class. This may be
- // used when deserializing a |ThreadTicks| structure, using a value known to
- // be compatible. It is not provided as a constructor because the integer type
- // may be unclear from the perspective of a caller.
- //
- // DEPRECATED - Do not use in new code. For deserializing ThreadTicks values,
- // prefer ThreadTicks + TimeDelta(). http://crbug.com/634507
- static constexpr ThreadTicks FromInternalValue(int64_t us) {
- return ThreadTicks(us);
- }
-
- private:
- friend class time_internal::TimeBase<ThreadTicks>;
-
- // Please use Now() or GetForThread() to create a new object. This is for
- // internal use and testing.
- constexpr explicit ThreadTicks(int64_t us) : TimeBase(us) {}
-
-#if defined(OS_WIN)
- FRIEND_TEST_ALL_PREFIXES(TimeTicks, TSCTicksPerSecond);
-
- // Returns the frequency of the TSC in ticks per second, or 0 if it hasn't
- // been measured yet. Needs to be guarded with a call to IsSupported().
- // This method is declared here rather than in the anonymous namespace to
- // allow testing.
- static double TSCTicksPerSecond();
-
- static void WaitUntilInitializedWin();
-#endif
-};
-
-// For logging use only.
-std::ostream& operator<<(std::ostream& os, ThreadTicks time_ticks);
-
-} // namespace base
-
-#endif // BASE_TIME_TIME_H_
diff --git a/base/time/time_conversion_posix.cc b/base/time/time_conversion_posix.cc
deleted file mode 100644
index ba0a2b2..0000000
--- a/base/time/time_conversion_posix.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/time/time.h"
-
-#include <stdint.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include <limits>
-
-#include "base/logging.h"
-
-namespace base {
-
-// static
-TimeDelta TimeDelta::FromTimeSpec(const timespec& ts) {
- return TimeDelta(ts.tv_sec * Time::kMicrosecondsPerSecond +
- ts.tv_nsec / Time::kNanosecondsPerMicrosecond);
-}
-
-struct timespec TimeDelta::ToTimeSpec() const {
- int64_t microseconds = InMicroseconds();
- time_t seconds = 0;
- if (microseconds >= Time::kMicrosecondsPerSecond) {
- seconds = InSeconds();
- microseconds -= seconds * Time::kMicrosecondsPerSecond;
- }
- struct timespec result = {
- seconds,
- static_cast<long>(microseconds * Time::kNanosecondsPerMicrosecond)};
- return result;
-}
-
-// static
-Time Time::FromTimeVal(struct timeval t) {
- DCHECK_LT(t.tv_usec, static_cast<int>(Time::kMicrosecondsPerSecond));
- DCHECK_GE(t.tv_usec, 0);
- if (t.tv_usec == 0 && t.tv_sec == 0)
- return Time();
- if (t.tv_usec == static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1 &&
- t.tv_sec == std::numeric_limits<time_t>::max())
- return Max();
- return Time((static_cast<int64_t>(t.tv_sec) * Time::kMicrosecondsPerSecond) +
- t.tv_usec + kTimeTToMicrosecondsOffset);
-}
-
-struct timeval Time::ToTimeVal() const {
- struct timeval result;
- if (is_null()) {
- result.tv_sec = 0;
- result.tv_usec = 0;
- return result;
- }
- if (is_max()) {
- result.tv_sec = std::numeric_limits<time_t>::max();
- result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1;
- return result;
- }
- int64_t us = us_ - kTimeTToMicrosecondsOffset;
- result.tv_sec = us / Time::kMicrosecondsPerSecond;
- result.tv_usec = us % Time::kMicrosecondsPerSecond;
- return result;
-}
-
-} // namespace base
diff --git a/base/time/time_mac.cc b/base/time/time_mac.cc
deleted file mode 100644
index 2d024e9..0000000
--- a/base/time/time_mac.cc
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/time/time.h"
-
-#include <CoreFoundation/CFDate.h>
-#include <CoreFoundation/CFTimeZone.h>
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include "base/logging.h"
-#include "base/mac/mach_logging.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_mach_port.h"
-#include "base/macros.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/time/time_override.h"
-#include "util/build_config.h"
-
-#if defined(OS_IOS)
-#include <time.h>
-#include "base/ios/ios_util.h"
-#endif
-
-namespace {
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-int64_t MachAbsoluteTimeToTicks(uint64_t mach_absolute_time) {
- static mach_timebase_info_data_t timebase_info;
- if (timebase_info.denom == 0) {
- // Zero-initialization of statics guarantees that denom will be 0 before
- // calling mach_timebase_info. mach_timebase_info will never set denom to
- // 0 as that would be invalid, so the zero-check can be used to determine
- // whether mach_timebase_info has already been called. This is
- // recommended by Apple's QA1398.
- kern_return_t kr = mach_timebase_info(&timebase_info);
- MACH_DCHECK(kr == KERN_SUCCESS, kr) << "mach_timebase_info";
- }
-
- // timebase_info converts absolute time tick units into nanoseconds. Convert
- // to microseconds up front to stave off overflows.
- base::CheckedNumeric<uint64_t> result(mach_absolute_time /
- base::Time::kNanosecondsPerMicrosecond);
- result *= timebase_info.numer;
- result /= timebase_info.denom;
-
- // Don't bother with the rollover handling that the Windows version does.
- // With numer and denom = 1 (the expected case), the 64-bit absolute time
- // reported in nanoseconds is enough to last nearly 585 years.
- return base::checked_cast<int64_t>(result.ValueOrDie());
-}
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
-
-// Returns monotonically growing number of ticks in microseconds since some
-// unspecified starting point.
-int64_t ComputeCurrentTicks() {
-#if defined(OS_IOS)
- // iOS 10 supports clock_gettime(CLOCK_MONOTONIC, ...), which is
- // around 15 times faster than sysctl() call. Use it if possible;
- // otherwise, fall back to sysctl().
- if (__builtin_available(iOS 10, *)) {
- struct timespec tp;
- if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
- return (int64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
- }
- }
-
- // On iOS mach_absolute_time stops while the device is sleeping. Instead use
- // now - KERN_BOOTTIME to get a time difference that is not impacted by clock
- // changes. KERN_BOOTTIME will be updated by the system whenever the system
- // clock change.
- struct timeval boottime;
- int mib[2] = {CTL_KERN, KERN_BOOTTIME};
- size_t size = sizeof(boottime);
- int kr = sysctl(mib, arraysize(mib), &boottime, &size, nullptr, 0);
- DCHECK_EQ(KERN_SUCCESS, kr);
- base::TimeDelta time_difference =
- base::subtle::TimeNowIgnoringOverride() -
- (base::Time::FromTimeT(boottime.tv_sec) +
- base::TimeDelta::FromMicroseconds(boottime.tv_usec));
- return time_difference.InMicroseconds();
-#else
- // mach_absolute_time is it when it comes to ticks on the Mac. Other calls
- // with less precision (such as TickCount) just call through to
- // mach_absolute_time.
- return MachAbsoluteTimeToTicks(mach_absolute_time());
-#endif // defined(OS_IOS)
-}
-
-int64_t ComputeThreadTicks() {
-#if defined(OS_IOS)
- NOTREACHED();
- return 0;
-#else
- base::mac::ScopedMachSendRight thread(mach_thread_self());
- mach_msg_type_number_t thread_info_count = THREAD_BASIC_INFO_COUNT;
- thread_basic_info_data_t thread_info_data;
-
- if (thread.get() == MACH_PORT_NULL) {
- DLOG(ERROR) << "Failed to get mach_thread_self()";
- return 0;
- }
-
- kern_return_t kr = thread_info(
- thread.get(), THREAD_BASIC_INFO,
- reinterpret_cast<thread_info_t>(&thread_info_data), &thread_info_count);
- MACH_DCHECK(kr == KERN_SUCCESS, kr) << "thread_info";
-
- base::CheckedNumeric<int64_t> absolute_micros(
- thread_info_data.user_time.seconds +
- thread_info_data.system_time.seconds);
- absolute_micros *= base::Time::kMicrosecondsPerSecond;
- absolute_micros += (thread_info_data.user_time.microseconds +
- thread_info_data.system_time.microseconds);
- return absolute_micros.ValueOrDie();
-#endif // defined(OS_IOS)
-}
-
-} // namespace
-
-namespace base {
-
-// The Time routines in this file use Mach and CoreFoundation APIs, since the
-// POSIX definition of time_t in Mac OS X wraps around after 2038--and
-// there are already cookie expiration dates, etc., past that time out in
-// the field. Using CFDate prevents that problem, and using mach_absolute_time
-// for TimeTicks gives us nice high-resolution interval timing.
-
-// Time -----------------------------------------------------------------------
-
-namespace subtle {
-Time TimeNowIgnoringOverride() {
- return Time::FromCFAbsoluteTime(CFAbsoluteTimeGetCurrent());
-}
-
-Time TimeNowFromSystemTimeIgnoringOverride() {
- // Just use TimeNowIgnoringOverride() because it returns the system time.
- return TimeNowIgnoringOverride();
-}
-} // namespace subtle
-
-// static
-Time Time::FromCFAbsoluteTime(CFAbsoluteTime t) {
- static_assert(std::numeric_limits<CFAbsoluteTime>::has_infinity,
- "CFAbsoluteTime must have an infinity value");
- if (t == 0)
- return Time(); // Consider 0 as a null Time.
- if (t == std::numeric_limits<CFAbsoluteTime>::infinity())
- return Max();
- return Time(static_cast<int64_t>((t + kCFAbsoluteTimeIntervalSince1970) *
- kMicrosecondsPerSecond) +
- kTimeTToMicrosecondsOffset);
-}
-
-CFAbsoluteTime Time::ToCFAbsoluteTime() const {
- static_assert(std::numeric_limits<CFAbsoluteTime>::has_infinity,
- "CFAbsoluteTime must have an infinity value");
- if (is_null())
- return 0; // Consider 0 as a null Time.
- if (is_max())
- return std::numeric_limits<CFAbsoluteTime>::infinity();
- return (static_cast<CFAbsoluteTime>(us_ - kTimeTToMicrosecondsOffset) /
- kMicrosecondsPerSecond) -
- kCFAbsoluteTimeIntervalSince1970;
-}
-
-// Note: These implementations of Time::FromExploded() and Time::Explode() are
-// only used on iOS now. Since Mac is now always 64-bit, we can use the POSIX
-// versions of these functions as time_t is not capped at year 2038 on 64-bit
-// builds. The POSIX functions are preferred since they don't suffer from some
-// performance problems that are present in these implementations.
-// See crbug.com/781601 for more details.
-#if defined(OS_IOS)
-// static
-bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) {
- base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
- is_local
- ? CFTimeZoneCopySystem()
- : CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, 0));
- base::ScopedCFTypeRef<CFCalendarRef> gregorian(CFCalendarCreateWithIdentifier(
- kCFAllocatorDefault, kCFGregorianCalendar));
- CFCalendarSetTimeZone(gregorian, time_zone);
- CFAbsoluteTime absolute_time;
- // 'S' is not defined in componentDesc in Apple documentation, but can be
- // found at http://www.opensource.apple.com/source/CF/CF-855.17/CFCalendar.c
- CFCalendarComposeAbsoluteTime(
- gregorian, &absolute_time, "yMdHmsS", exploded.year, exploded.month,
- exploded.day_of_month, exploded.hour, exploded.minute, exploded.second,
- exploded.millisecond);
- CFAbsoluteTime seconds = absolute_time + kCFAbsoluteTimeIntervalSince1970;
-
- // CFAbsolutTime is typedef of double. Convert seconds to
- // microseconds and then cast to int64. If
- // it cannot be suited to int64, then fail to avoid overflows.
- double microseconds =
- (seconds * kMicrosecondsPerSecond) + kTimeTToMicrosecondsOffset;
- if (microseconds > std::numeric_limits<int64_t>::max() ||
- microseconds < std::numeric_limits<int64_t>::min()) {
- *time = Time(0);
- return false;
- }
-
- base::Time converted_time = Time(static_cast<int64_t>(microseconds));
-
- // If |exploded.day_of_month| is set to 31
- // on a 28-30 day month, it will return the first day of the next month.
- // Thus round-trip the time and compare the initial |exploded| with
- // |utc_to_exploded| time.
- base::Time::Exploded to_exploded;
- if (!is_local)
- converted_time.UTCExplode(&to_exploded);
- else
- converted_time.LocalExplode(&to_exploded);
-
- if (ExplodedMostlyEquals(to_exploded, exploded)) {
- *time = converted_time;
- return true;
- }
-
- *time = Time(0);
- return false;
-}
-
-void Time::Explode(bool is_local, Exploded* exploded) const {
- // Avoid rounding issues, by only putting the integral number of seconds
- // (rounded towards -infinity) into a |CFAbsoluteTime| (which is a |double|).
- int64_t microsecond = us_ % kMicrosecondsPerSecond;
- if (microsecond < 0)
- microsecond += kMicrosecondsPerSecond;
- CFAbsoluteTime seconds = ((us_ - microsecond - kTimeTToMicrosecondsOffset) /
- kMicrosecondsPerSecond) -
- kCFAbsoluteTimeIntervalSince1970;
-
- base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
- is_local
- ? CFTimeZoneCopySystem()
- : CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, 0));
- base::ScopedCFTypeRef<CFCalendarRef> gregorian(CFCalendarCreateWithIdentifier(
- kCFAllocatorDefault, kCFGregorianCalendar));
- CFCalendarSetTimeZone(gregorian, time_zone);
- int second, day_of_week;
- // 'E' sets the day of week, but is not defined in componentDesc in Apple
- // documentation. It can be found in open source code here:
- // http://www.opensource.apple.com/source/CF/CF-855.17/CFCalendar.c
- CFCalendarDecomposeAbsoluteTime(gregorian, seconds, "yMdHmsE",
- &exploded->year, &exploded->month,
- &exploded->day_of_month, &exploded->hour,
- &exploded->minute, &second, &day_of_week);
- // Make sure seconds are rounded down towards -infinity.
- exploded->second = floor(second);
- // |Exploded|'s convention for day of week is 0 = Sunday, i.e. different
- // from CF's 1 = Sunday.
- exploded->day_of_week = (day_of_week - 1) % 7;
- // Calculate milliseconds ourselves, since we rounded the |seconds|, making
- // sure to round towards -infinity.
- exploded->millisecond =
- (microsecond >= 0) ? microsecond / kMicrosecondsPerMillisecond
- : (microsecond - kMicrosecondsPerMillisecond + 1) /
- kMicrosecondsPerMillisecond;
-}
-#endif // OS_IOS
-
-// TimeTicks ------------------------------------------------------------------
-
-namespace subtle {
-TimeTicks TimeTicksNowIgnoringOverride() {
- return TimeTicks() + TimeDelta::FromMicroseconds(ComputeCurrentTicks());
-}
-} // namespace subtle
-
-// static
-bool TimeTicks::IsHighResolution() {
- return true;
-}
-
-// static
-bool TimeTicks::IsConsistentAcrossProcesses() {
- return true;
-}
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-// static
-TimeTicks TimeTicks::FromMachAbsoluteTime(uint64_t mach_absolute_time) {
- return TimeTicks(MachAbsoluteTimeToTicks(mach_absolute_time));
-}
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
-
-// static
-TimeTicks::Clock TimeTicks::GetClock() {
-#if defined(OS_IOS)
- return Clock::IOS_CF_ABSOLUTE_TIME_MINUS_KERN_BOOTTIME;
-#else
- return Clock::MAC_MACH_ABSOLUTE_TIME;
-#endif // defined(OS_IOS)
-}
-
-// ThreadTicks ----------------------------------------------------------------
-
-namespace subtle {
-ThreadTicks ThreadTicksNowIgnoringOverride() {
- return ThreadTicks() + TimeDelta::FromMicroseconds(ComputeThreadTicks());
-}
-} // namespace subtle
-
-} // namespace base
diff --git a/base/time/time_now_posix.cc b/base/time/time_now_posix.cc
deleted file mode 100644
index a3f4602..0000000
--- a/base/time/time_now_posix.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/time/time.h"
-
-#include <stdint.h>
-#include <sys/time.h>
-#include <time.h>
-#if defined(OS_ANDROID) && !defined(__LP64__)
-#include <time64.h>
-#endif
-#include <unistd.h>
-
-#include "base/logging.h"
-#include "base/numerics/safe_math.h"
-#include "base/time/time_override.h"
-#include "util/build_config.h"
-
-// Ensure the Fuchsia and Mac builds do not include this module. Instead,
-// non-POSIX implementation is used for sampling the system clocks.
-#if defined(OS_FUCHSIA) || defined(OS_MACOSX)
-#error "This implementation is for POSIX platforms other than Fuchsia or Mac."
-#endif
-
-namespace {
-
-int64_t ConvertTimespecToMicros(const struct timespec& ts) {
- // On 32-bit systems, the calculation cannot overflow int64_t.
- // 2**32 * 1000000 + 2**64 / 1000 < 2**63
- if (sizeof(ts.tv_sec) <= 4 && sizeof(ts.tv_nsec) <= 8) {
- int64_t result = ts.tv_sec;
- result *= base::Time::kMicrosecondsPerSecond;
- result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond);
- return result;
- } else {
- base::CheckedNumeric<int64_t> result(ts.tv_sec);
- result *= base::Time::kMicrosecondsPerSecond;
- result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond);
- return result.ValueOrDie();
- }
-}
-
-// Helper function to get results from clock_gettime() and convert to a
-// microsecond timebase. Minimum requirement is MONOTONIC_CLOCK to be supported
-// on the system. FreeBSD 6 has CLOCK_MONOTONIC but defines
-// _POSIX_MONOTONIC_CLOCK to -1.
-#if (defined(OS_POSIX) && defined(_POSIX_MONOTONIC_CLOCK) && \
- _POSIX_MONOTONIC_CLOCK >= 0) || \
- defined(OS_BSD) || defined(OS_ANDROID)
-int64_t ClockNow(clockid_t clk_id) {
- struct timespec ts;
- CHECK(clock_gettime(clk_id, &ts) == 0);
- return ConvertTimespecToMicros(ts);
-}
-#else // _POSIX_MONOTONIC_CLOCK
-#error No usable tick clock function on this platform.
-#endif // _POSIX_MONOTONIC_CLOCK
-
-} // namespace
-
-namespace base {
-
-// Time -----------------------------------------------------------------------
-
-namespace subtle {
-Time TimeNowIgnoringOverride() {
- struct timeval tv;
- struct timezone tz = {0, 0}; // UTC
- CHECK(gettimeofday(&tv, &tz) == 0);
- // Combine seconds and microseconds in a 64-bit field containing microseconds
- // since the epoch. That's enough for nearly 600 centuries. Adjust from
- // Unix (1970) to Windows (1601) epoch.
- return Time() + TimeDelta::FromMicroseconds(
- (tv.tv_sec * Time::kMicrosecondsPerSecond + tv.tv_usec) +
- Time::kTimeTToMicrosecondsOffset);
-}
-
-Time TimeNowFromSystemTimeIgnoringOverride() {
- // Just use TimeNowIgnoringOverride() because it returns the system time.
- return TimeNowIgnoringOverride();
-}
-} // namespace subtle
-
-// TimeTicks ------------------------------------------------------------------
-
-namespace subtle {
-TimeTicks TimeTicksNowIgnoringOverride() {
- return TimeTicks() + TimeDelta::FromMicroseconds(ClockNow(CLOCK_MONOTONIC));
-}
-} // namespace subtle
-
-// static
-TimeTicks::Clock TimeTicks::GetClock() {
- return Clock::LINUX_CLOCK_MONOTONIC;
-}
-
-// static
-bool TimeTicks::IsHighResolution() {
- return true;
-}
-
-// static
-bool TimeTicks::IsConsistentAcrossProcesses() {
- return true;
-}
-
-// ThreadTicks ----------------------------------------------------------------
-
-namespace subtle {
-ThreadTicks ThreadTicksNowIgnoringOverride() {
-#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \
- defined(OS_ANDROID)
- return ThreadTicks() +
- TimeDelta::FromMicroseconds(ClockNow(CLOCK_THREAD_CPUTIME_ID));
-#else
- NOTREACHED();
- return ThreadTicks();
-#endif
-}
-} // namespace subtle
-
-} // namespace base
diff --git a/base/time/time_override.cc b/base/time/time_override.cc
deleted file mode 100644
index 09692b5..0000000
--- a/base/time/time_override.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/time/time_override.h"
-
-namespace base {
-namespace subtle {
-
-#if DCHECK_IS_ON()
-// static
-bool ScopedTimeClockOverrides::overrides_active_ = false;
-#endif
-
-ScopedTimeClockOverrides::ScopedTimeClockOverrides(
- TimeNowFunction time_override,
- TimeTicksNowFunction time_ticks_override,
- ThreadTicksNowFunction thread_ticks_override) {
-#if DCHECK_IS_ON()
- DCHECK(!overrides_active_);
- overrides_active_ = true;
-#endif
- if (time_override) {
- internal::g_time_now_function = time_override;
- internal::g_time_now_from_system_time_function = time_override;
- }
- if (time_ticks_override)
- internal::g_time_ticks_now_function = time_ticks_override;
- if (thread_ticks_override)
- internal::g_thread_ticks_now_function = thread_ticks_override;
-}
-
-ScopedTimeClockOverrides::~ScopedTimeClockOverrides() {
- internal::g_time_now_function = &TimeNowIgnoringOverride;
- internal::g_time_now_from_system_time_function =
- &TimeNowFromSystemTimeIgnoringOverride;
- internal::g_time_ticks_now_function = &TimeTicksNowIgnoringOverride;
- internal::g_thread_ticks_now_function = &ThreadTicksNowIgnoringOverride;
-#if DCHECK_IS_ON()
- overrides_active_ = false;
-#endif
-}
-
-} // namespace subtle
-} // namespace base
diff --git a/base/time/time_override.h b/base/time/time_override.h
deleted file mode 100644
index 4e068f7..0000000
--- a/base/time/time_override.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_TIME_TIME_OVERRIDE_H_
-#define BASE_TIME_TIME_OVERRIDE_H_
-
-#include "base/time/time.h"
-
-namespace base {
-
-using TimeNowFunction = decltype(&Time::Now);
-using TimeTicksNowFunction = decltype(&TimeTicks::Now);
-using ThreadTicksNowFunction = decltype(&ThreadTicks::Now);
-
-// Time overrides should be used with extreme caution. Discuss with //base/time
-// OWNERS before adding a new one.
-namespace subtle {
-
-// Override the return value of Time::Now and Time::NowFromSystemTime /
-// TimeTicks::Now / ThreadTicks::Now to emulate time, e.g. for tests or to
-// modify progression of time. Note that the override should be set while
-// single-threaded and before the first call to Now() to avoid threading issues
-// and inconsistencies in returned values. Nested overrides are not allowed.
-class ScopedTimeClockOverrides {
- public:
- // Pass |nullptr| for any override if it shouldn't be overriden.
- ScopedTimeClockOverrides(TimeNowFunction time_override,
- TimeTicksNowFunction time_ticks_override,
- ThreadTicksNowFunction thread_ticks_override);
-
- // Restores the platform default Now() functions.
- ~ScopedTimeClockOverrides();
-
- private:
-#if DCHECK_IS_ON()
- static bool overrides_active_;
-#endif
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedTimeClockOverrides);
-};
-
-// These methods return the platform default Time::Now / TimeTicks::Now /
-// ThreadTicks::Now values even while an override is in place. These methods
-// should only be used in places where emulated time should be disregarded. For
-// example, they can be used to implement test timeouts for tests that may
-// override time.
-Time TimeNowIgnoringOverride();
-Time TimeNowFromSystemTimeIgnoringOverride();
-TimeTicks TimeTicksNowIgnoringOverride();
-ThreadTicks ThreadTicksNowIgnoringOverride();
-
-} // namespace subtle
-
-namespace internal {
-
-// These function pointers are used by platform-independent implementations of
-// the Now() methods and ScopedTimeClockOverrides. They are set to point to the
-// respective NowIgnoringOverride functions by default, but can also be set by
-// platform-specific code to select a default implementation at runtime, thereby
-// avoiding the indirection via the NowIgnoringOverride functions. Note that the
-// pointers can be overridden and later reset to the NowIgnoringOverride
-// functions by ScopedTimeClockOverrides.
-extern TimeNowFunction g_time_now_function;
-extern TimeNowFunction g_time_now_from_system_time_function;
-extern TimeTicksNowFunction g_time_ticks_now_function;
-extern ThreadTicksNowFunction g_thread_ticks_now_function;
-
-} // namespace internal
-
-} // namespace base
-
-#endif // BASE_TIME_TIME_OVERRIDE_H_
diff --git a/base/time/time_win.cc b/base/time/time_win.cc
deleted file mode 100644
index 8632369..0000000
--- a/base/time/time_win.cc
+++ /dev/null
@@ -1,542 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Windows Timer Primer
-//
-// A good article: http://www.ddj.com/windows/184416651
-// A good mozilla bug: http://bugzilla.mozilla.org/show_bug.cgi?id=363258
-//
-// The default windows timer, GetSystemTimeAsFileTime is not very precise.
-// It is only good to ~15.5ms.
-//
-// QueryPerformanceCounter is the logical choice for a high-precision timer.
-// However, it is known to be buggy on some hardware. Specifically, it can
-// sometimes "jump". On laptops, QPC can also be very expensive to call.
-// It's 3-4x slower than timeGetTime() on desktops, but can be 10x slower
-// on laptops. A unittest exists which will show the relative cost of various
-// timers on any system.
-//
-// The next logical choice is timeGetTime(). timeGetTime has a precision of
-// 1ms, but only if you call APIs (timeBeginPeriod()) which affect all other
-// applications on the system. By default, precision is only 15.5ms.
-// Unfortunately, we don't want to call timeBeginPeriod because we don't
-// want to affect other applications. Further, on mobile platforms, use of
-// faster multimedia timers can hurt battery life. See the intel
-// article about this here:
-// http://softwarecommunity.intel.com/articles/eng/1086.htm
-//
-// To work around all this, we're going to generally use timeGetTime(). We
-// will only increase the system-wide timer if we're not running on battery
-// power.
-
-#include "base/time/time.h"
-
-#include <windows.h>
-
-#include <mmsystem.h>
-#include <stdint.h>
-
-#include <mutex>
-
-#include "base/bit_cast.h"
-#include "base/logging.h"
-#include "base/threading/platform_thread.h"
-#include "base/time/time_override.h"
-
-namespace base {
-
-namespace {
-
-// From MSDN, FILETIME "Contains a 64-bit value representing the number of
-// 100-nanosecond intervals since January 1, 1601 (UTC)."
-int64_t FileTimeToMicroseconds(const FILETIME& ft) {
- // Need to bit_cast to fix alignment, then divide by 10 to convert
- // 100-nanoseconds to microseconds. This only works on little-endian
- // machines.
- return bit_cast<int64_t, FILETIME>(ft) / 10;
-}
-
-void MicrosecondsToFileTime(int64_t us, FILETIME* ft) {
- DCHECK_GE(us, 0LL) << "Time is less than 0, negative values are not "
- "representable in FILETIME";
-
- // Multiply by 10 to convert microseconds to 100-nanoseconds. Bit_cast will
- // handle alignment problems. This only works on little-endian machines.
- *ft = bit_cast<FILETIME, int64_t>(us * 10);
-}
-
-int64_t CurrentWallclockMicroseconds() {
- FILETIME ft;
- ::GetSystemTimeAsFileTime(&ft);
- return FileTimeToMicroseconds(ft);
-}
-
-// Time between resampling the un-granular clock for this API.
-constexpr TimeDelta kMaxTimeToAvoidDrift = TimeDelta::FromSeconds(60);
-
-int64_t g_initial_time = 0;
-TimeTicks g_initial_ticks;
-
-void InitializeClock() {
- g_initial_ticks = subtle::TimeTicksNowIgnoringOverride();
- g_initial_time = CurrentWallclockMicroseconds();
-}
-
-// The two values that ActivateHighResolutionTimer uses to set the systemwide
-// timer interrupt frequency on Windows. It controls how precise timers are
-// but also has a big impact on battery life.
-const int kMinTimerIntervalHighResMs = 1;
-const int kMinTimerIntervalLowResMs = 4;
-// Track if kMinTimerIntervalHighResMs or kMinTimerIntervalLowResMs is active.
-bool g_high_res_timer_enabled = false;
-// How many times the high resolution timer has been called.
-uint32_t g_high_res_timer_count = 0;
-// Start time of the high resolution timer usage monitoring. This is needed
-// to calculate the usage as percentage of the total elapsed time.
-TimeTicks g_high_res_timer_usage_start;
-// The cumulative time the high resolution timer has been in use since
-// |g_high_res_timer_usage_start| moment.
-TimeDelta g_high_res_timer_usage;
-// Timestamp of the last activation change of the high resolution timer. This
-// is used to calculate the cumulative usage.
-TimeTicks g_high_res_timer_last_activation;
-// The lock to control access to the above two variables.
-std::mutex* GetHighResLock() {
- static auto* lock = new std::mutex();
- return lock;
-}
-
-// Returns the current value of the performance counter.
-uint64_t QPCNowRaw() {
- LARGE_INTEGER perf_counter_now = {};
- // According to the MSDN documentation for QueryPerformanceCounter(), this
- // will never fail on systems that run XP or later.
- // https://msdn.microsoft.com/library/windows/desktop/ms644904.aspx
- ::QueryPerformanceCounter(&perf_counter_now);
- return perf_counter_now.QuadPart;
-}
-
-bool SafeConvertToWord(int in, WORD* out) {
- CheckedNumeric<WORD> result = in;
- *out = result.ValueOrDefault(std::numeric_limits<WORD>::max());
- return result.IsValid();
-}
-
-} // namespace
-
-// Time -----------------------------------------------------------------------
-
-namespace subtle {
-Time TimeNowIgnoringOverride() {
- if (g_initial_time == 0)
- InitializeClock();
-
- // We implement time using the high-resolution timers so that we can get
- // timeouts which are smaller than 10-15ms. If we just used
- // CurrentWallclockMicroseconds(), we'd have the less-granular timer.
- //
- // To make this work, we initialize the clock (g_initial_time) and the
- // counter (initial_ctr). To compute the initial time, we can check
- // the number of ticks that have elapsed, and compute the delta.
- //
- // To avoid any drift, we periodically resync the counters to the system
- // clock.
- while (true) {
- TimeTicks ticks = TimeTicksNowIgnoringOverride();
-
- // Calculate the time elapsed since we started our timer
- TimeDelta elapsed = ticks - g_initial_ticks;
-
- // Check if enough time has elapsed that we need to resync the clock.
- if (elapsed > kMaxTimeToAvoidDrift) {
- InitializeClock();
- continue;
- }
-
- return Time() + elapsed + TimeDelta::FromMicroseconds(g_initial_time);
- }
-}
-
-Time TimeNowFromSystemTimeIgnoringOverride() {
- // Force resync.
- InitializeClock();
- return Time() + TimeDelta::FromMicroseconds(g_initial_time);
-}
-} // namespace subtle
-
-// static
-Time Time::FromFileTime(FILETIME ft) {
- if (bit_cast<int64_t, FILETIME>(ft) == 0)
- return Time();
- if (ft.dwHighDateTime == std::numeric_limits<DWORD>::max() &&
- ft.dwLowDateTime == std::numeric_limits<DWORD>::max())
- return Max();
- return Time(FileTimeToMicroseconds(ft));
-}
-
-FILETIME Time::ToFileTime() const {
- if (is_null())
- return bit_cast<FILETIME, int64_t>(0);
- if (is_max()) {
- FILETIME result;
- result.dwHighDateTime = std::numeric_limits<DWORD>::max();
- result.dwLowDateTime = std::numeric_limits<DWORD>::max();
- return result;
- }
- FILETIME utc_ft;
- MicrosecondsToFileTime(us_, &utc_ft);
- return utc_ft;
-}
-
-// static
-void Time::EnableHighResolutionTimer(bool enable) {
- std::lock_guard<std::mutex> lock(*GetHighResLock());
- if (g_high_res_timer_enabled == enable)
- return;
- g_high_res_timer_enabled = enable;
- if (!g_high_res_timer_count)
- return;
- // Since g_high_res_timer_count != 0, an ActivateHighResolutionTimer(true)
- // was called which called timeBeginPeriod with g_high_res_timer_enabled
- // with a value which is the opposite of |enable|. With that information we
- // call timeEndPeriod with the same value used in timeBeginPeriod and
- // therefore undo the period effect.
- if (enable) {
- timeEndPeriod(kMinTimerIntervalLowResMs);
- timeBeginPeriod(kMinTimerIntervalHighResMs);
- } else {
- timeEndPeriod(kMinTimerIntervalHighResMs);
- timeBeginPeriod(kMinTimerIntervalLowResMs);
- }
-}
-
-// static
-bool Time::ActivateHighResolutionTimer(bool activating) {
- // We only do work on the transition from zero to one or one to zero so we
- // can easily undo the effect (if necessary) when EnableHighResolutionTimer is
- // called.
- const uint32_t max = std::numeric_limits<uint32_t>::max();
-
- std::lock_guard<std::mutex> lock(*GetHighResLock());
- UINT period = g_high_res_timer_enabled ? kMinTimerIntervalHighResMs
- : kMinTimerIntervalLowResMs;
- if (activating) {
- DCHECK_NE(g_high_res_timer_count, max);
- ++g_high_res_timer_count;
- if (g_high_res_timer_count == 1) {
- g_high_res_timer_last_activation = subtle::TimeTicksNowIgnoringOverride();
- timeBeginPeriod(period);
- }
- } else {
- DCHECK_NE(g_high_res_timer_count, 0u);
- --g_high_res_timer_count;
- if (g_high_res_timer_count == 0) {
- g_high_res_timer_usage += subtle::TimeTicksNowIgnoringOverride() -
- g_high_res_timer_last_activation;
- timeEndPeriod(period);
- }
- }
- return (period == kMinTimerIntervalHighResMs);
-}
-
-// static
-bool Time::IsHighResolutionTimerInUse() {
- std::lock_guard<std::mutex> lock(*GetHighResLock());
- return g_high_res_timer_enabled && g_high_res_timer_count > 0;
-}
-
-// static
-void Time::ResetHighResolutionTimerUsage() {
- std::lock_guard<std::mutex> lock(*GetHighResLock());
- g_high_res_timer_usage = TimeDelta();
- g_high_res_timer_usage_start = subtle::TimeTicksNowIgnoringOverride();
- if (g_high_res_timer_count > 0)
- g_high_res_timer_last_activation = g_high_res_timer_usage_start;
-}
-
-// static
-double Time::GetHighResolutionTimerUsage() {
- std::lock_guard<std::mutex> lock(*GetHighResLock());
- TimeTicks now = subtle::TimeTicksNowIgnoringOverride();
- TimeDelta elapsed_time = now - g_high_res_timer_usage_start;
- if (elapsed_time.is_zero()) {
- // This is unexpected but possible if TimeTicks resolution is low and
- // GetHighResolutionTimerUsage() is called promptly after
- // ResetHighResolutionTimerUsage().
- return 0.0;
- }
- TimeDelta used_time = g_high_res_timer_usage;
- if (g_high_res_timer_count > 0) {
- // If currently activated add the remainder of time since the last
- // activation.
- used_time += now - g_high_res_timer_last_activation;
- }
- return used_time.InMillisecondsF() / elapsed_time.InMillisecondsF() * 100;
-}
-
-// TimeTicks ------------------------------------------------------------------
-
-namespace {
-
-// Discussion of tick counter options on Windows:
-//
-// (1) CPU cycle counter. (Retrieved via RDTSC)
-// The CPU counter provides the highest resolution time stamp and is the least
-// expensive to retrieve. However, on older CPUs, two issues can affect its
-// reliability: First it is maintained per processor and not synchronized
-// between processors. Also, the counters will change frequency due to thermal
-// and power changes, and stop in some states.
-//
-// (2) QueryPerformanceCounter (QPC). The QPC counter provides a high-
-// resolution (<1 microsecond) time stamp. On most hardware running today, it
-// auto-detects and uses the constant-rate RDTSC counter to provide extremely
-// efficient and reliable time stamps.
-//
-// On older CPUs where RDTSC is unreliable, it falls back to using more
-// expensive (20X to 40X more costly) alternate clocks, such as HPET or the ACPI
-// PM timer, and can involve system calls; and all this is up to the HAL (with
-// some help from ACPI). According to
-// http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx, in the
-// worst case, it gets the counter from the rollover interrupt on the
-// programmable interrupt timer. In best cases, the HAL may conclude that the
-// RDTSC counter runs at a constant frequency, then it uses that instead. On
-// multiprocessor machines, it will try to verify the values returned from
-// RDTSC on each processor are consistent with each other, and apply a handful
-// of workarounds for known buggy hardware. In other words, QPC is supposed to
-// give consistent results on a multiprocessor computer, but for older CPUs it
-// can be unreliable due bugs in BIOS or HAL.
-//
-// (3) System time. The system time provides a low-resolution (from ~1 to ~15.6
-// milliseconds) time stamp but is comparatively less expensive to retrieve and
-// more reliable. Time::EnableHighResolutionTimer() and
-// Time::ActivateHighResolutionTimer() can be called to alter the resolution of
-// this timer; and also other Windows applications can alter it, affecting this
-// one.
-
-TimeTicks InitialNowFunction();
-
-// See "threading notes" in InitializeNowFunctionPointer() for details on how
-// concurrent reads/writes to these globals has been made safe.
-TimeTicksNowFunction g_time_ticks_now_ignoring_override_function =
- &InitialNowFunction;
-int64_t g_qpc_ticks_per_second = 0;
-
-// As of January 2015, use of <atomic> is forbidden in Chromium code. This is
-// what std::atomic_thread_fence does on Windows on all Intel architectures when
-// the memory_order argument is anything but std::memory_order_seq_cst:
-#define ATOMIC_THREAD_FENCE(memory_order) _ReadWriteBarrier();
-
-TimeDelta QPCValueToTimeDelta(LONGLONG qpc_value) {
- // Ensure that the assignment to |g_qpc_ticks_per_second|, made in
- // InitializeNowFunctionPointer(), has happened by this point.
- ATOMIC_THREAD_FENCE(memory_order_acquire);
-
- DCHECK_GT(g_qpc_ticks_per_second, 0);
-
- // If the QPC Value is below the overflow threshold, we proceed with
- // simple multiply and divide.
- if (qpc_value < Time::kQPCOverflowThreshold) {
- return TimeDelta::FromMicroseconds(
- qpc_value * Time::kMicrosecondsPerSecond / g_qpc_ticks_per_second);
- }
- // Otherwise, calculate microseconds in a round about manner to avoid
- // overflow and precision issues.
- int64_t whole_seconds = qpc_value / g_qpc_ticks_per_second;
- int64_t leftover_ticks = qpc_value - (whole_seconds * g_qpc_ticks_per_second);
- return TimeDelta::FromMicroseconds(
- (whole_seconds * Time::kMicrosecondsPerSecond) +
- ((leftover_ticks * Time::kMicrosecondsPerSecond) /
- g_qpc_ticks_per_second));
-}
-
-TimeTicks QPCNow() {
- return TimeTicks() + QPCValueToTimeDelta(QPCNowRaw());
-}
-
-void InitializeNowFunctionPointer() {
- LARGE_INTEGER ticks_per_sec = {};
- if (!QueryPerformanceFrequency(&ticks_per_sec))
- ticks_per_sec.QuadPart = 0;
-
- TimeTicksNowFunction now_function = &QPCNow;
-
- // Threading note 1: In an unlikely race condition, it's possible for two or
- // more threads to enter InitializeNowFunctionPointer() in parallel. This is
- // not a problem since all threads should end up writing out the same values
- // to the global variables.
- //
- // Threading note 2: A release fence is placed here to ensure, from the
- // perspective of other threads using the function pointers, that the
- // assignment to |g_qpc_ticks_per_second| happens before the function pointers
- // are changed.
- g_qpc_ticks_per_second = ticks_per_sec.QuadPart;
- ATOMIC_THREAD_FENCE(memory_order_release);
- // Also set g_time_ticks_now_function to avoid the additional indirection via
- // TimeTicksNowIgnoringOverride() for future calls to TimeTicks::Now(). But
- // g_time_ticks_now_function may have already be overridden.
- if (internal::g_time_ticks_now_function ==
- &subtle::TimeTicksNowIgnoringOverride) {
- internal::g_time_ticks_now_function = now_function;
- }
- g_time_ticks_now_ignoring_override_function = now_function;
-}
-
-TimeTicks InitialNowFunction() {
- InitializeNowFunctionPointer();
- return g_time_ticks_now_ignoring_override_function();
-}
-
-} // namespace
-
-namespace subtle {
-TimeTicks TimeTicksNowIgnoringOverride() {
- return g_time_ticks_now_ignoring_override_function();
-}
-} // namespace subtle
-
-// static
-bool TimeTicks::IsHighResolution() {
- if (g_time_ticks_now_ignoring_override_function == &InitialNowFunction)
- InitializeNowFunctionPointer();
- return g_time_ticks_now_ignoring_override_function == &QPCNow;
-}
-
-// static
-bool TimeTicks::IsConsistentAcrossProcesses() {
- // According to Windows documentation [1] QPC is consistent post-Windows
- // Vista. So if we are using QPC then we are consistent which is the same as
- // being high resolution.
- //
- // [1]
- // https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
- //
- // "In general, the performance counter results are consistent across all
- // processors in multi-core and multi-processor systems, even when measured on
- // different threads or processes. Here are some exceptions to this rule:
- // - Pre-Windows Vista operating systems that run on certain processors might
- // violate this consistency because of one of these reasons:
- // 1. The hardware processors have a non-invariant TSC and the BIOS
- // doesn't indicate this condition correctly.
- // 2. The TSC synchronization algorithm that was used wasn't suitable for
- // systems with large numbers of processors."
- return IsHighResolution();
-}
-
-// static
-TimeTicks::Clock TimeTicks::GetClock() {
- return IsHighResolution() ? Clock::WIN_QPC
- : Clock::WIN_ROLLOVER_PROTECTED_TIME_GET_TIME;
-}
-
-// ThreadTicks ----------------------------------------------------------------
-
-namespace subtle {
-ThreadTicks ThreadTicksNowIgnoringOverride() {
- return ThreadTicks::GetForThread(PlatformThread::CurrentHandle());
-}
-} // namespace subtle
-
-// static
-ThreadTicks ThreadTicks::GetForThread(
- const PlatformThreadHandle& thread_handle) {
- DCHECK(IsSupported());
-
- // Get the number of TSC ticks used by the current thread.
- ULONG64 thread_cycle_time = 0;
- ::QueryThreadCycleTime(thread_handle.platform_handle(), &thread_cycle_time);
-
- // Get the frequency of the TSC.
- double tsc_ticks_per_second = TSCTicksPerSecond();
- if (tsc_ticks_per_second == 0)
- return ThreadTicks();
-
- // Return the CPU time of the current thread.
- double thread_time_seconds = thread_cycle_time / tsc_ticks_per_second;
- return ThreadTicks(
- static_cast<int64_t>(thread_time_seconds * Time::kMicrosecondsPerSecond));
-}
-
-// static
-void ThreadTicks::WaitUntilInitializedWin() {
- while (TSCTicksPerSecond() == 0)
- ::Sleep(10);
-}
-
-double ThreadTicks::TSCTicksPerSecond() {
- DCHECK(IsSupported());
-
- // The value returned by QueryPerformanceFrequency() cannot be used as the TSC
- // frequency, because there is no guarantee that the TSC frequency is equal to
- // the performance counter frequency.
-
- // The TSC frequency is cached in a static variable because it takes some time
- // to compute it.
- static double tsc_ticks_per_second = 0;
- if (tsc_ticks_per_second != 0)
- return tsc_ticks_per_second;
-
- // Increase the thread priority to reduces the chances of having a context
- // switch during a reading of the TSC and the performance counter.
- int previous_priority = ::GetThreadPriority(::GetCurrentThread());
- ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
-
- // The first time that this function is called, make an initial reading of the
- // TSC and the performance counter.
- static const uint64_t tsc_initial = __rdtsc();
- static const uint64_t perf_counter_initial = QPCNowRaw();
-
- // Make a another reading of the TSC and the performance counter every time
- // that this function is called.
- uint64_t tsc_now = __rdtsc();
- uint64_t perf_counter_now = QPCNowRaw();
-
- // Reset the thread priority.
- ::SetThreadPriority(::GetCurrentThread(), previous_priority);
-
- // Make sure that at least 50 ms elapsed between the 2 readings. The first
- // time that this function is called, we don't expect this to be the case.
- // Note: The longer the elapsed time between the 2 readings is, the more
- // accurate the computed TSC frequency will be. The 50 ms value was
- // chosen because local benchmarks show that it allows us to get a
- // stddev of less than 1 tick/us between multiple runs.
- // Note: According to the MSDN documentation for QueryPerformanceFrequency(),
- // this will never fail on systems that run XP or later.
- // https://msdn.microsoft.com/library/windows/desktop/ms644905.aspx
- LARGE_INTEGER perf_counter_frequency = {};
- ::QueryPerformanceFrequency(&perf_counter_frequency);
- DCHECK_GE(perf_counter_now, perf_counter_initial);
- uint64_t perf_counter_ticks = perf_counter_now - perf_counter_initial;
- double elapsed_time_seconds =
- perf_counter_ticks / static_cast<double>(perf_counter_frequency.QuadPart);
-
- static constexpr double kMinimumEvaluationPeriodSeconds = 0.05;
- if (elapsed_time_seconds < kMinimumEvaluationPeriodSeconds)
- return 0;
-
- // Compute the frequency of the TSC.
- DCHECK_GE(tsc_now, tsc_initial);
- uint64_t tsc_ticks = tsc_now - tsc_initial;
- tsc_ticks_per_second = tsc_ticks / elapsed_time_seconds;
-
- return tsc_ticks_per_second;
-}
-
-// static
-TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) {
- return TimeTicks() + QPCValueToTimeDelta(qpc_value);
-}
-
-// TimeDelta ------------------------------------------------------------------
-
-// static
-TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) {
- return QPCValueToTimeDelta(qpc_value);
-}
-
-// static
-TimeDelta TimeDelta::FromFileTime(FILETIME ft) {
- return TimeDelta::FromMicroseconds(FileTimeToMicroseconds(ft));
-}
-
-} // namespace base
diff --git a/base/timer/elapsed_timer.cc b/base/timer/elapsed_timer.cc
index ca86ccd..68992f4 100644
--- a/base/timer/elapsed_timer.cc
+++ b/base/timer/elapsed_timer.cc
@@ -7,7 +7,7 @@
namespace base {
ElapsedTimer::ElapsedTimer() {
- begin_ = TimeTicks::Now();
+ begin_ = TicksNow();
}
ElapsedTimer::ElapsedTimer(ElapsedTimer&& other) {
@@ -18,8 +18,8 @@
begin_ = other.begin_;
}
-TimeDelta ElapsedTimer::Elapsed() const {
- return TimeTicks::Now() - begin_;
+TickDelta ElapsedTimer::Elapsed() const {
+ return TicksDelta(TicksNow(), begin_);
}
} // namespace base
diff --git a/base/timer/elapsed_timer.h b/base/timer/elapsed_timer.h
index c9d254b..fbbc83d 100644
--- a/base/timer/elapsed_timer.h
+++ b/base/timer/elapsed_timer.h
@@ -6,11 +6,11 @@
#define BASE_TIMER_ELAPSED_TIMER_H_
#include "base/macros.h"
-#include "base/time/time.h"
+#include "util/ticks.h"
namespace base {
-// A simple wrapper around TimeTicks::Now().
+// A simple wrapper around TicksNow().
class ElapsedTimer {
public:
ElapsedTimer();
@@ -19,10 +19,10 @@
void operator=(ElapsedTimer&& other);
// Returns the time elapsed since object construction.
- TimeDelta Elapsed() const;
+ TickDelta Elapsed() const;
private:
- TimeTicks begin_;
+ Ticks begin_;
DISALLOW_COPY_AND_ASSIGN(ElapsedTimer);
};
diff --git a/build/gen.py b/build/gen.py
index f253bc3..44435f6 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -254,8 +254,6 @@
'base/strings/utf_string_conversion_utils.cc',
'base/strings/utf_string_conversions.cc',
'base/third_party/icu/icu_utf.cc',
- 'base/time/clock.cc',
- 'base/time/time.cc',
'base/timer/elapsed_timer.cc',
'base/value_iterators.cc',
'base/values.cc',
@@ -385,6 +383,7 @@
'util/msg_loop.cc',
'util/semaphore.cc',
'util/sys_info.cc',
+ 'util/ticks.cc',
'util/worker_pool.cc',
], 'tool': 'cxx', 'include_dirs': []},
}
@@ -469,15 +468,11 @@
'base/posix/file_descriptor_shuffle.cc',
'base/posix/safe_strerror.cc',
'base/strings/string16.cc',
- 'base/threading/platform_thread_posix.cc',
- 'base/time/time_conversion_posix.cc',
])
if is_linux:
static_libraries['base']['sources'].extend([
'base/strings/sys_string_conversions_posix.cc',
- 'base/time/time_now_posix.cc',
- 'base/threading/platform_thread_linux.cc',
])
libs.extend([
'-lc',
@@ -498,8 +493,6 @@
'base/mac/scoped_mach_port.cc',
'base/mac/scoped_nsautorelease_pool.mm',
'base/strings/sys_string_conversions_mac.mm',
- 'base/time/time_mac.cc',
- 'base/threading/platform_thread_mac.mm',
])
libs.extend([
@@ -515,8 +508,6 @@
'base/files/file_util_win.cc',
'base/files/file_win.cc',
'base/strings/sys_string_conversions_win.cc',
- 'base/threading/platform_thread_win.cc',
- 'base/time/time_win.cc',
'base/win/registry.cc',
'base/win/scoped_handle.cc',
'base/win/scoped_process_information.cc',
diff --git a/tools/gn/command_gen.cc b/tools/gn/command_gen.cc
index af5dd1f..eb1b4d2 100644
--- a/tools/gn/command_gen.cc
+++ b/tools/gn/command_gen.cc
@@ -455,7 +455,7 @@
return 1;
}
- base::TimeDelta elapsed_time = timer.Elapsed();
+ TickDelta elapsed_time = timer.Elapsed();
if (!command_line->HasSwitch(switches::kQuiet)) {
OutputString("Done. ", DECORATION_GREEN);
diff --git a/tools/gn/filesystem_utils_unittest.cc b/tools/gn/filesystem_utils_unittest.cc
index 8bfd52c..87e37f8 100644
--- a/tools/gn/filesystem_utils_unittest.cc
+++ b/tools/gn/filesystem_utils_unittest.cc
@@ -3,12 +3,14 @@
// found in the LICENSE file.
#include "tools/gn/filesystem_utils.h"
+
+#include <thread>
+
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/threading/platform_thread.h"
#include "tools/gn/target.h"
#include "util/build_config.h"
#include "util/test/test.h"
@@ -645,15 +647,17 @@
base::File::Info file_info;
ASSERT_TRUE(base::GetFileInfo(file_path, &file_info));
- base::Time last_modified = file_info.last_modified;
+ Ticks last_modified = file_info.last_modified;
+ {
+ using namespace std::chrono_literals;
#if defined(OS_MACOSX)
- // Modification times are in seconds in HFS on Mac.
- base::TimeDelta sleep_time = base::TimeDelta::FromSeconds(1);
+ // Modification times are in seconds in HFS on Mac.
+ std::this_thread::sleep_for(1s);
#else
- base::TimeDelta sleep_time = base::TimeDelta::FromMilliseconds(1);
+ std::this_thread::sleep_for(1ms);
#endif
- base::PlatformThread::Sleep(sleep_time);
+ }
// Don't write if contents is the same.
EXPECT_TRUE(WriteFileIfChanged(file_path, data, nullptr));
diff --git a/tools/gn/function_exec_script.cc b/tools/gn/function_exec_script.cc
index e1ada23..e0b6265 100644
--- a/tools/gn/function_exec_script.cc
+++ b/tools/gn/function_exec_script.cc
@@ -7,7 +7,6 @@
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
#include "tools/gn/err.h"
#include "tools/gn/exec_process.h"
#include "tools/gn/filesystem_utils.h"
@@ -19,6 +18,7 @@
#include "tools/gn/trace.h"
#include "tools/gn/value.h"
#include "util/build_config.h"
+#include "util/ticks.h"
namespace functions {
@@ -198,7 +198,7 @@
// Log command line for debugging help.
trace.SetCommandLine(cmdline);
- base::TimeTicks begin_exec;
+ Ticks begin_exec = 0;
if (g_scheduler->verbose_logging()) {
#if defined(OS_WIN)
g_scheduler->Log("Pythoning",
@@ -206,7 +206,7 @@
#else
g_scheduler->Log("Pythoning", cmdline.GetCommandLineString());
#endif
- begin_exec = base::TimeTicks::Now();
+ begin_exec = TicksNow();
}
base::FilePath startup_dir =
@@ -239,7 +239,7 @@
"Pythoning",
script_source_path + " took " +
base::Int64ToString(
- (base::TimeTicks::Now() - begin_exec).InMilliseconds()) +
+ TicksDelta(TicksNow(), begin_exec).InMilliseconds()) +
"ms");
}
diff --git a/tools/gn/function_write_file_unittest.cc b/tools/gn/function_write_file_unittest.cc
index b12f037..95414ce 100644
--- a/tools/gn/function_write_file_unittest.cc
+++ b/tools/gn/function_write_file_unittest.cc
@@ -70,13 +70,21 @@
EXPECT_EQ("line 1\n2\n", result_contents);
// Test that the file is not rewritten if the contents are not changed.
- // Start by setting the modified time to something old to avoid clock
- // resolution issues.
- base::Time old_time = base::Time::Now() - base::TimeDelta::FromDays(1);
base::File foo_file(foo_name, base::File::FLAG_OPEN | base::File::FLAG_READ |
base::File::FLAG_WRITE);
ASSERT_TRUE(foo_file.IsValid());
- foo_file.SetTimes(old_time, old_time);
+
+ // Start by setting the modified time to something old to avoid clock
+ // resolution issues.
+#if defined(OS_WIN)
+ FILETIME last_access_filetime = {};
+ FILETIME last_modified_filetime = {};
+ ASSERT_TRUE(::SetFileTime(foo_file.GetPlatformFile(), nullptr,
+ &last_access_filetime, &last_modified_filetime));
+#else
+ timespec ts_times[2] = {};
+ ASSERT_EQ(futimens(foo_file.GetPlatformFile(), ts_times), 0);
+#endif
// Read the current time to avoid timer resolution issues when comparing
// below.
diff --git a/tools/gn/import_manager.cc b/tools/gn/import_manager.cc
index f4aa32a..36c7088 100644
--- a/tools/gn/import_manager.cc
+++ b/tools/gn/import_manager.cc
@@ -11,6 +11,7 @@
#include "tools/gn/scheduler.h"
#include "tools/gn/scope_per_file_provider.h"
#include "tools/gn/trace.h"
+#include "util/ticks.h"
namespace {
@@ -75,8 +76,9 @@
Scope* scope,
Err* err) {
// Key for the current import on the current thread in imports_in_progress_.
- std::string key =
- std::to_string(base::PlatformThread::CurrentId()) + file.value();
+ std::stringstream ss;
+ ss << std::this_thread::get_id() << file.value();
+ std::string key = ss.str();
// See if we have a cached import, but be careful to actually do the scope
// copying outside of the lock.
@@ -101,7 +103,7 @@
// is already processing the import.
const Scope* import_scope = nullptr;
{
- base::TimeTicks import_block_begin = base::TimeTicks::Now();
+ Ticks import_block_begin = TicksNow();
std::lock_guard<std::mutex> lock(import_info->load_lock);
if (!import_info->scope) {
@@ -117,14 +119,14 @@
} else {
// Add trace if this thread was blocked for a long period of time and did
// not load the import itself.
- base::TimeTicks import_block_end = base::TimeTicks::Now();
- constexpr auto kImportBlockTraceThreshold =
- base::TimeDelta::FromMilliseconds(20);
+ Ticks import_block_end = TicksNow();
+ constexpr auto kImportBlockTraceThresholdMS = 20;
if (TracingEnabled() &&
- import_block_end - import_block_begin > kImportBlockTraceThreshold) {
+ TicksDelta(import_block_end, import_block_begin).InMilliseconds() >
+ kImportBlockTraceThresholdMS) {
auto* import_block_trace =
new TraceItem(TraceItem::TRACE_IMPORT_BLOCK, file.value(),
- base::PlatformThread::CurrentId());
+ std::this_thread::get_id());
import_block_trace->set_begin(import_block_begin);
import_block_trace->set_end(import_block_end);
AddTrace(import_block_trace);
diff --git a/tools/gn/trace.cc b/tools/gn/trace.cc
index 76fc00d..184c450 100644
--- a/tools/gn/trace.cc
+++ b/tools/gn/trace.cc
@@ -56,7 +56,7 @@
};
bool DurationGreater(const TraceItem* a, const TraceItem* b) {
- return a->delta() > b->delta();
+ return a->delta().raw() > b->delta().raw();
}
bool CoalescedDurationGreater(const Coalesced& a, const Coalesced& b) {
@@ -112,7 +112,7 @@
TraceItem::TraceItem(Type type,
const std::string& name,
- base::PlatformThreadId thread_id)
+ std::thread::id thread_id)
: type_(type), name_(name), thread_id_(thread_id) {}
TraceItem::~TraceItem() = default;
@@ -120,8 +120,8 @@
ScopedTrace::ScopedTrace(TraceItem::Type t, const std::string& name)
: item_(nullptr), done_(false) {
if (trace_log) {
- item_ = new TraceItem(t, name, base::PlatformThread::CurrentId());
- item_->set_begin(base::TimeTicks::Now());
+ item_ = new TraceItem(t, name, std::this_thread::get_id());
+ item_->set_begin(TicksNow());
}
}
@@ -129,8 +129,8 @@
: item_(nullptr), done_(false) {
if (trace_log) {
item_ = new TraceItem(t, label.GetUserVisibleName(false),
- base::PlatformThread::CurrentId());
- item_->set_begin(base::TimeTicks::Now());
+ std::this_thread::get_id());
+ item_->set_begin(TicksNow());
}
}
@@ -152,7 +152,7 @@
if (!done_) {
done_ = true;
if (trace_log) {
- item_->set_end(base::TimeTicks::Now());
+ item_->set_end(TicksNow());
AddTrace(item_);
}
}
@@ -244,7 +244,7 @@
// Write main thread metadata (assume this is being written on the main
// thread).
- out << "{\"pid\":0,\"tid\":" << base::PlatformThread::CurrentId();
+ out << "{\"pid\":0,\"tid\":" << std::this_thread::get_id();
out << ",\"ts\":0,\"ph\":\"M\",";
out << "\"name\":\"thread_name\",\"args\":{\"name\":\"Main thread\"}},";
@@ -255,7 +255,7 @@
if (i != 0)
out << ",";
out << "{\"pid\":0,\"tid\":" << item.thread_id();
- out << ",\"ts\":" << item.begin().ToInternalValue();
+ out << ",\"ts\":" << item.begin();
out << ",\"ph\":\"X\""; // "X" = complete event with begin & duration.
out << ",\"dur\":" << item.delta().InMicroseconds();
diff --git a/tools/gn/trace.h b/tools/gn/trace.h
index 3b91aaa..f4f06df 100644
--- a/tools/gn/trace.h
+++ b/tools/gn/trace.h
@@ -6,10 +6,10 @@
#define TOOLS_GN_TRACE_H_
#include <string>
+#include <thread>
#include "base/macros.h"
-#include "base/threading/platform_thread.h"
-#include "base/time/time.h"
+#include "util/ticks.h"
class Label;
@@ -35,21 +35,19 @@
TRACE_CHECK_HEADERS, // All files.
};
- TraceItem(Type type,
- const std::string& name,
- base::PlatformThreadId thread_id);
+ TraceItem(Type type, const std::string& name, std::thread::id thread_id);
~TraceItem();
Type type() const { return type_; }
const std::string& name() const { return name_; }
- base::PlatformThreadId thread_id() const { return thread_id_; }
+ std::thread::id thread_id() const { return thread_id_; }
- base::TimeTicks begin() const { return begin_; }
- void set_begin(base::TimeTicks b) { begin_ = b; }
- base::TimeTicks end() const { return end_; }
- void set_end(base::TimeTicks e) { end_ = e; }
+ Ticks begin() const { return begin_; }
+ void set_begin(Ticks b) { begin_ = b; }
+ Ticks end() const { return end_; }
+ void set_end(Ticks e) { end_ = e; }
- base::TimeDelta delta() const { return end_ - begin_; }
+ TickDelta delta() const { return TicksDelta(end_, begin_); }
// Optional toolchain label.
const std::string& toolchain() const { return toolchain_; }
@@ -62,10 +60,10 @@
private:
Type type_;
std::string name_;
- base::PlatformThreadId thread_id_;
+ std::thread::id thread_id_;
- base::TimeTicks begin_;
- base::TimeTicks end_;
+ Ticks begin_;
+ Ticks end_;
std::string toolchain_;
std::string cmdline_;
diff --git a/tools/gn/unique_vector.h b/tools/gn/unique_vector.h
index 25b4f5b..732b663 100644
--- a/tools/gn/unique_vector.h
+++ b/tools/gn/unique_vector.h
@@ -9,6 +9,7 @@
#include <algorithm>
#include <unordered_set>
+#include <vector>
namespace internal {
diff --git a/tools/gn/unique_vector_unittest.cc b/tools/gn/unique_vector_unittest.cc
index 87430ea..afea1e2 100644
--- a/tools/gn/unique_vector_unittest.cc
+++ b/tools/gn/unique_vector_unittest.cc
@@ -6,7 +6,6 @@
#include <algorithm>
-#include "base/time/time.h"
#include "tools/gn/unique_vector.h"
#include "util/test/test.h"
diff --git a/util/ticks.cc b/util/ticks.cc
new file mode 100644
index 0000000..df35375
--- /dev/null
+++ b/util/ticks.cc
@@ -0,0 +1,93 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ticks.h"
+
+#include "base/logging.h"
+#include "build_config.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#elif defined(OS_MACOSX)
+#include <mach/mach_time.h>
+#elif defined(OS_LINUX)
+#include <time.h>
+#else
+#error Port.
+#endif
+
+namespace {
+
+bool g_initialized;
+
+#if defined(OS_WIN)
+LARGE_INTEGER g_frequency;
+LARGE_INTEGER g_start;
+#elif defined(OS_MACOSX)
+mach_timebase_info_data_t g_timebase;
+uint64_t g_start;
+#elif defined(OS_LINUX)
+uint64_t g_start;
+#else
+#error Port.
+#endif
+
+constexpr uint64_t kNano = 1'000'000'000;
+
+void Init() {
+ DCHECK(!g_initialized);
+
+#if defined(OS_WIN)
+ QueryPerformanceFrequency(&g_frequency);
+ QueryPerformanceCounter(&g_start);
+#elif defined(OS_MACOSX)
+ mach_timebase_info(&g_timebase);
+ g_start = (mach_absolute_time() * g_timebase.numer) / g_timebase.denom;
+#elif defined(OS_LINUX)
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ g_start = static_cast<uint64_t>(ts.tv_sec) * kNano +
+ static_cast<uint64_t>(ts.tv_nsec);
+#else
+#error Port.
+#endif
+
+ g_initialized = true;
+}
+
+} // namespace
+
+Ticks TicksNow() {
+ static bool initialized = []() {
+ Init();
+ return true;
+ }();
+ DCHECK(initialized);
+
+ Ticks now;
+
+#if defined(OS_WIN)
+ LARGE_INTEGER t;
+ QueryPerformanceCounter(&t);
+ now = ((t.QuadPart - g_start.QuadPart) * kNano) / g_frequency.QuadPart;
+#elif defined(OS_MACOSX)
+ now =
+ ((mach_absolute_time() * g_timebase.numer) / g_timebase.denom) - g_start;
+#elif defined(OS_LINUX)
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ now = (static_cast<uint64_t>(ts.tv_sec) * kNano +
+ static_cast<uint64_t>(ts.tv_nsec)) -
+ g_start;
+#else
+#error Port.
+#endif
+
+ return now;
+}
+
+TickDelta TicksDelta(Ticks new_ticks, Ticks old_ticks) {
+ DCHECK(new_ticks >= old_ticks);
+ return TickDelta(new_ticks - old_ticks);
+}
diff --git a/util/ticks.h b/util/ticks.h
new file mode 100644
index 0000000..fcbde05
--- /dev/null
+++ b/util/ticks.h
@@ -0,0 +1,45 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UTIL_TICKS_H_
+#define UTIL_TICKS_H_
+
+#include <stdint.h>
+
+using Ticks = uint64_t;
+
+class TickDelta {
+ public:
+ explicit TickDelta(uint64_t delta) : delta_(delta) {}
+
+ double InSecondsF() const { return delta_ / 1000000000.0; }
+ double InMillisecondsF() const { return delta_ / 1000000.0; }
+ double InMicrosecondsF() const { return delta_ / 1000.0; }
+ double InNanosecondsF() const { return delta_; }
+
+ uint64_t InSeconds() const { return delta_ / 1000000000; }
+ uint64_t InMilliseconds() const { return delta_ / 1000000; }
+ uint64_t InMicroseconds() const { return delta_ / 1000; }
+ uint64_t InNanoseconds() const { return delta_; }
+
+ uint64_t raw() const { return delta_; }
+
+ private:
+ uint64_t delta_;
+};
+
+Ticks TicksNow();
+
+TickDelta TicksDelta(Ticks new_ticks, Ticks old_ticks);
+
+class ElapsedTimer {
+ public:
+ ElapsedTimer() : start_(TicksNow()) {}
+ TickDelta Elapsed() { return TicksDelta(TicksNow(), start_); }
+
+ private:
+ Ticks start_;
+};
+
+#endif // UTIL_TICKS_H_