Make MessageQueue processing an optional feature of FakeClock
This is used to avoid thread processing in simulated time
controller. This saves up to 30% execution time in debug builds.
Bug: webrtc:10365
Change-Id: Ie83dfb2468d371e4687d28c776acf7e23eb411d1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133173
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27666}
diff --git a/media/base/rtp_data_engine_unittest.cc b/media/base/rtp_data_engine_unittest.cc
index 97d7e18..ffb91d7 100644
--- a/media/base/rtp_data_engine_unittest.cc
+++ b/media/base/rtp_data_engine_unittest.cc
@@ -58,9 +58,7 @@
receiver_.reset(new FakeDataReceiver());
}
- void SetNow(double now) {
- clock_.SetTimeNanos(now * rtc::kNumNanosecsPerSec);
- }
+ void SetNow(double now) { clock_.SetTime(webrtc::Timestamp::seconds(now)); }
cricket::RtpDataEngine* CreateEngine() {
cricket::RtpDataEngine* dme = new cricket::RtpDataEngine();
diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc
index f97d631..a92f4ff 100644
--- a/p2p/base/p2p_transport_channel_unittest.cc
+++ b/p2p/base/p2p_transport_channel_unittest.cc
@@ -611,7 +611,7 @@
DestroyChannels();
}
- void TestSendRecv(rtc::FakeClock* clock) {
+ void TestSendRecv(rtc::ThreadProcessingFakeClock* clock) {
for (int i = 0; i < 10; ++i) {
const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
int len = static_cast<int>(strlen(data));
@@ -3093,10 +3093,11 @@
this, &P2PTransportChannelPingTest::OnChannelStateChanged);
}
- Connection* WaitForConnectionTo(P2PTransportChannel* ch,
- const std::string& ip,
- int port_num,
- rtc::FakeClock* clock = nullptr) {
+ Connection* WaitForConnectionTo(
+ P2PTransportChannel* ch,
+ const std::string& ip,
+ int port_num,
+ rtc::ThreadProcessingFakeClock* clock = nullptr) {
if (clock == nullptr) {
EXPECT_TRUE_WAIT(GetConnectionTo(ch, ip, port_num) != nullptr,
kMediumTimeout);
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 59eca29..e7ad807 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -1084,6 +1084,7 @@
":checks",
":rtc_base",
"../api/units:time_delta",
+ "../api/units:timestamp",
"memory:fifo_buffer",
"third_party/sigslot",
"//third_party/abseil-cpp/absl/algorithm:container",
diff --git a/rtc_base/fake_clock.cc b/rtc_base/fake_clock.cc
index 6b7d96b..b9f0ee9 100644
--- a/rtc_base/fake_clock.cc
+++ b/rtc_base/fake_clock.cc
@@ -17,28 +17,40 @@
int64_t FakeClock::TimeNanos() const {
CritScope cs(&lock_);
- return time_;
+ return time_ns_;
}
-void FakeClock::SetTimeNanos(int64_t nanos) {
- {
- CritScope cs(&lock_);
- RTC_DCHECK(nanos >= time_);
- time_ = nanos;
- }
+void FakeClock::SetTime(webrtc::Timestamp new_time) {
+ CritScope cs(&lock_);
+ RTC_DCHECK(new_time.us() * 1000 >= time_ns_);
+ time_ns_ = new_time.us() * 1000;
+}
+
+void FakeClock::AdvanceTime(webrtc::TimeDelta delta) {
+ CritScope cs(&lock_);
+ time_ns_ += delta.ns();
+}
+
+void ThreadProcessingFakeClock::SetTime(webrtc::Timestamp time) {
+ clock_.SetTime(time);
// If message queues are waiting in a socket select() with a timeout provided
// by the OS, they should wake up and dispatch all messages that are ready.
MessageQueueManager::ProcessAllMessageQueuesForTesting();
}
-void FakeClock::AdvanceTime(webrtc::TimeDelta delta) {
- {
- CritScope cs(&lock_);
- time_ += delta.ns();
- }
+void ThreadProcessingFakeClock::AdvanceTime(webrtc::TimeDelta delta) {
+ clock_.AdvanceTime(delta);
MessageQueueManager::ProcessAllMessageQueuesForTesting();
}
+ScopedBaseFakeClock::ScopedBaseFakeClock() {
+ prev_clock_ = SetClockForTesting(this);
+}
+
+ScopedBaseFakeClock::~ScopedBaseFakeClock() {
+ SetClockForTesting(prev_clock_);
+}
+
ScopedFakeClock::ScopedFakeClock() {
prev_clock_ = SetClockForTesting(this);
}
diff --git a/rtc_base/fake_clock.h b/rtc_base/fake_clock.h
index dce1539..0a29f60 100644
--- a/rtc_base/fake_clock.h
+++ b/rtc_base/fake_clock.h
@@ -14,6 +14,7 @@
#include <stdint.h>
#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/time_utils.h"
@@ -26,7 +27,10 @@
// TODO(deadbeef): Unify with webrtc::SimulatedClock.
class FakeClock : public ClockInterface {
public:
- ~FakeClock() override {}
+ FakeClock() = default;
+ FakeClock(const FakeClock&) = delete;
+ FakeClock& operator=(const FakeClock&) = delete;
+ ~FakeClock() override = default;
// ClockInterface implementation.
int64_t TimeNanos() const override;
@@ -34,28 +38,45 @@
// Methods that can be used by the test to control the time.
// Should only be used to set a time in the future.
- void SetTimeNanos(int64_t nanos);
- void SetTimeMicros(int64_t micros) {
- SetTimeNanos(kNumNanosecsPerMicrosec * micros);
- }
+ void SetTime(webrtc::Timestamp new_time);
void AdvanceTime(webrtc::TimeDelta delta);
+
+ private:
+ CriticalSection lock_;
+ int64_t time_ns_ RTC_GUARDED_BY(lock_) = 0;
+};
+
+class ThreadProcessingFakeClock : public ClockInterface {
+ public:
+ int64_t TimeNanos() const override { return clock_.TimeNanos(); }
+ void SetTime(webrtc::Timestamp time);
+ void SetTimeMicros(int64_t micros) {
+ SetTime(webrtc::Timestamp ::us(micros));
+ }
+ void AdvanceTime(webrtc::TimeDelta delta);
void AdvanceTimeMicros(int64_t micros) {
AdvanceTime(webrtc::TimeDelta::us(micros));
}
-
private:
- CriticalSection lock_;
- int64_t time_ RTC_GUARDED_BY(lock_) = 0;
+ FakeClock clock_;
};
// Helper class that sets itself as the global clock in its constructor and
// unsets it in its destructor.
-class ScopedFakeClock : public FakeClock {
+class ScopedBaseFakeClock : public FakeClock {
+ public:
+ ScopedBaseFakeClock();
+ ~ScopedBaseFakeClock() override;
+
+ private:
+ ClockInterface* prev_clock_;
+};
+
+// TODO(srte): Rename this to reflect that it also does thread processing.
+class ScopedFakeClock : public ThreadProcessingFakeClock {
public:
ScopedFakeClock();
- ScopedFakeClock(const ScopedFakeClock&) = delete;
- ScopedFakeClock& operator=(const ScopedFakeClock&) = delete;
~ScopedFakeClock() override;
private:
diff --git a/rtc_base/test_client.cc b/rtc_base/test_client.cc
index 274b6ca..1264602 100644
--- a/rtc_base/test_client.cc
+++ b/rtc_base/test_client.cc
@@ -28,7 +28,7 @@
: TestClient(std::move(socket), nullptr) {}
TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket,
- FakeClock* fake_clock)
+ ThreadProcessingFakeClock* fake_clock)
: fake_clock_(fake_clock),
socket_(std::move(socket)),
prev_packet_timestamp_(-1) {
diff --git a/rtc_base/test_client.h b/rtc_base/test_client.h
index fb8a2f9..bbae12c 100644
--- a/rtc_base/test_client.h
+++ b/rtc_base/test_client.h
@@ -48,7 +48,8 @@
// Create a test client that will use a fake clock. NextPacket needs to wait
// for a packet to be received, and thus it needs to advance the fake clock
// if the test is using one, rather than just sleeping.
- TestClient(std::unique_ptr<AsyncPacketSocket> socket, FakeClock* fake_clock);
+ TestClient(std::unique_ptr<AsyncPacketSocket> socket,
+ ThreadProcessingFakeClock* fake_clock);
~TestClient() override;
SocketAddress address() const { return socket_->GetLocalAddress(); }
@@ -102,7 +103,7 @@
bool CheckTimestamp(int64_t packet_timestamp);
void AdvanceTime(int ms);
- FakeClock* fake_clock_ = nullptr;
+ ThreadProcessingFakeClock* fake_clock_ = nullptr;
CriticalSection crit_;
std::unique_ptr<AsyncPacketSocket> socket_;
std::vector<std::unique_ptr<Packet>> packets_;
diff --git a/rtc_base/time_utils_unittest.cc b/rtc_base/time_utils_unittest.cc
index b736ad8..aeb9daf 100644
--- a/rtc_base/time_utils_unittest.cc
+++ b/rtc_base/time_utils_unittest.cc
@@ -217,11 +217,11 @@
FakeClock clock;
SetClockForTesting(&clock);
- clock.SetTimeNanos(987654321);
+ clock.SetTime(webrtc::Timestamp::us(987654));
EXPECT_EQ(987u, Time32());
EXPECT_EQ(987, TimeMillis());
EXPECT_EQ(987654, TimeMicros());
- EXPECT_EQ(987654321, TimeNanos());
+ EXPECT_EQ(987654000, TimeNanos());
EXPECT_EQ(1000u, TimeAfter(13));
SetClockForTesting(nullptr);
@@ -234,12 +234,12 @@
EXPECT_EQ(0, clock.TimeNanos());
}
-TEST(FakeClock, SetTimeNanos) {
+TEST(FakeClock, SetTime) {
FakeClock clock;
- clock.SetTimeNanos(123);
- EXPECT_EQ(123, clock.TimeNanos());
- clock.SetTimeNanos(456);
- EXPECT_EQ(456, clock.TimeNanos());
+ clock.SetTime(webrtc::Timestamp::us(123));
+ EXPECT_EQ(123000, clock.TimeNanos());
+ clock.SetTime(webrtc::Timestamp::us(456));
+ EXPECT_EQ(456000, clock.TimeNanos());
}
TEST(FakeClock, AdvanceTime) {
@@ -261,7 +261,7 @@
TEST(FakeClock, SettingTimeWakesThreads) {
int64_t real_start_time_ms = TimeMillis();
- FakeClock clock;
+ ThreadProcessingFakeClock clock;
SetClockForTesting(&clock);
std::unique_ptr<Thread> worker(Thread::CreateWithSocketServer());
diff --git a/rtc_base/virtual_socket_server.cc b/rtc_base/virtual_socket_server.cc
index 0c621c9..83cf058 100644
--- a/rtc_base/virtual_socket_server.cc
+++ b/rtc_base/virtual_socket_server.cc
@@ -523,7 +523,7 @@
VirtualSocketServer::VirtualSocketServer() : VirtualSocketServer(nullptr) {}
-VirtualSocketServer::VirtualSocketServer(FakeClock* fake_clock)
+VirtualSocketServer::VirtualSocketServer(ThreadProcessingFakeClock* fake_clock)
: fake_clock_(fake_clock),
msg_queue_(nullptr),
stop_on_idle_(false),
diff --git a/rtc_base/virtual_socket_server.h b/rtc_base/virtual_socket_server.h
index 610c0fb..6d6d18a 100644
--- a/rtc_base/virtual_socket_server.h
+++ b/rtc_base/virtual_socket_server.h
@@ -37,7 +37,7 @@
// This constructor needs to be used if the test uses a fake clock and
// ProcessMessagesUntilIdle, since ProcessMessagesUntilIdle needs a way of
// advancing time.
- explicit VirtualSocketServer(FakeClock* fake_clock);
+ explicit VirtualSocketServer(ThreadProcessingFakeClock* fake_clock);
~VirtualSocketServer() override;
// The default route indicates which local address to use when a socket is
@@ -263,7 +263,7 @@
// May be null if the test doesn't use a fake clock, or it does but doesn't
// use ProcessMessagesUntilIdle.
- FakeClock* fake_clock_ = nullptr;
+ ThreadProcessingFakeClock* fake_clock_ = nullptr;
// Used to implement Wait/WakeUp.
Event wakeup_;
diff --git a/test/time_controller/simulated_time_controller.cc b/test/time_controller/simulated_time_controller.cc
index 885732b..561559a 100644
--- a/test/time_controller/simulated_time_controller.cc
+++ b/test/time_controller/simulated_time_controller.cc
@@ -401,7 +401,7 @@
GlobalSimulatedTimeController::GlobalSimulatedTimeController(
Timestamp start_time)
: sim_clock_(start_time.us()), impl_(start_time) {
- global_clock_.SetTimeMicros(start_time.us());
+ global_clock_.SetTime(start_time);
}
GlobalSimulatedTimeController::~GlobalSimulatedTimeController() = default;
@@ -431,7 +431,7 @@
auto delta = next_time - current_time;
current_time = next_time;
sim_clock_.AdvanceTimeMicroseconds(delta.us());
- global_clock_.AdvanceTimeMicros(delta.us());
+ global_clock_.AdvanceTime(delta);
}
}
diff --git a/test/time_controller/simulated_time_controller.h b/test/time_controller/simulated_time_controller.h
index b870fa3..214a150 100644
--- a/test/time_controller/simulated_time_controller.h
+++ b/test/time_controller/simulated_time_controller.h
@@ -94,7 +94,7 @@
void InvokeWithControlledYield(std::function<void()> closure) override;
private:
- rtc::ScopedFakeClock global_clock_;
+ rtc::ScopedBaseFakeClock global_clock_;
// Provides simulated CurrentNtpInMilliseconds()
SimulatedClock sim_clock_;
sim_time_impl::SimulatedTimeControllerImpl impl_;