Introduces rtc_base/synchronization/mutex.h.
This change introduces a new non-reentrant mutex to WebRTC. It
enables eventual migration to Abseil's mutex.
The mutex types supportable by webrtc::Mutex are
- absl::Mutex
- CriticalSection (Windows only)
- pthread_mutex (POSIX only)
In addition to introducing the mutexes, the CL also changes
PacketBuffer to use the new mutex instead of rtc::CriticalSection.
The method of yielding from critical_section.cc was given a
mini-cleanup and YieldCurrentThread() was added to
rtc_base/synchronization/yield.h/cc.
Additionally, google_benchmark benchmarks for the mutexes were added
(test courtesy of danilchap@), and some results from a pthread/Abseil
shootout were added showing Abseil has the advantage in higher
contention.
Bug: webrtc:11567, webrtc:11634
Change-Id: Iaec324ccb32ec3851bf6db3fd290f5ea5dee4c81
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176230
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31443}
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 6443a7b..798ab03 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -192,6 +192,7 @@
"../../rtc_base/experiments:min_video_bitrate_experiment",
"../../rtc_base/experiments:rate_control_settings",
"../../rtc_base/experiments:rtt_mult_experiment",
+ "../../rtc_base/synchronization:mutex",
"../../rtc_base/synchronization:sequence_checker",
"../../rtc_base/task_utils:repeating_task",
"../../rtc_base/third_party/base64",
diff --git a/modules/video_coding/packet_buffer.cc b/modules/video_coding/packet_buffer.cc
index d62dc84..ad82211 100644
--- a/modules/video_coding/packet_buffer.cc
+++ b/modules/video_coding/packet_buffer.cc
@@ -78,7 +78,7 @@
PacketBuffer::InsertResult PacketBuffer::InsertPacket(
std::unique_ptr<PacketBuffer::Packet> packet) {
PacketBuffer::InsertResult result;
- rtc::CritScope lock(&crit_);
+ MutexLock lock(&mutex_);
uint16_t seq_num = packet->seq_num;
size_t index = seq_num % buffer_.size();
@@ -136,7 +136,7 @@
}
void PacketBuffer::ClearTo(uint16_t seq_num) {
- rtc::CritScope lock(&crit_);
+ MutexLock lock(&mutex_);
// We have already cleared past this sequence number, no need to do anything.
if (is_cleared_to_first_seq_num_ &&
AheadOf<uint16_t>(first_seq_num_, seq_num)) {
@@ -173,25 +173,25 @@
}
void PacketBuffer::Clear() {
- rtc::CritScope lock(&crit_);
+ MutexLock lock(&mutex_);
ClearInternal();
}
PacketBuffer::InsertResult PacketBuffer::InsertPadding(uint16_t seq_num) {
PacketBuffer::InsertResult result;
- rtc::CritScope lock(&crit_);
+ MutexLock lock(&mutex_);
UpdateMissingPackets(seq_num);
result.packets = FindFrames(static_cast<uint16_t>(seq_num + 1));
return result;
}
absl::optional<int64_t> PacketBuffer::LastReceivedPacketMs() const {
- rtc::CritScope lock(&crit_);
+ MutexLock lock(&mutex_);
return last_received_packet_ms_;
}
absl::optional<int64_t> PacketBuffer::LastReceivedKeyframePacketMs() const {
- rtc::CritScope lock(&crit_);
+ MutexLock lock(&mutex_);
return last_received_keyframe_packet_ms_;
}
diff --git a/modules/video_coding/packet_buffer.h b/modules/video_coding/packet_buffer.h
index e4dc237..508fa83 100644
--- a/modules/video_coding/packet_buffer.h
+++ b/modules/video_coding/packet_buffer.h
@@ -22,8 +22,8 @@
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
#include "rtc_base/copy_on_write_buffer.h"
-#include "rtc_base/critical_section.h"
#include "rtc_base/numerics/sequence_number_util.h"
+#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread_annotations.h"
#include "system_wrappers/include/clock.h"
@@ -83,67 +83,67 @@
~PacketBuffer();
InsertResult InsertPacket(std::unique_ptr<Packet> packet) ABSL_MUST_USE_RESULT
- RTC_LOCKS_EXCLUDED(crit_);
+ RTC_LOCKS_EXCLUDED(mutex_);
InsertResult InsertPadding(uint16_t seq_num) ABSL_MUST_USE_RESULT
- RTC_LOCKS_EXCLUDED(crit_);
- void ClearTo(uint16_t seq_num) RTC_LOCKS_EXCLUDED(crit_);
- void Clear() RTC_LOCKS_EXCLUDED(crit_);
+ RTC_LOCKS_EXCLUDED(mutex_);
+ void ClearTo(uint16_t seq_num) RTC_LOCKS_EXCLUDED(mutex_);
+ void Clear() RTC_LOCKS_EXCLUDED(mutex_);
// Timestamp (not RTP timestamp) of the last received packet/keyframe packet.
absl::optional<int64_t> LastReceivedPacketMs() const
- RTC_LOCKS_EXCLUDED(crit_);
+ RTC_LOCKS_EXCLUDED(mutex_);
absl::optional<int64_t> LastReceivedKeyframePacketMs() const
- RTC_LOCKS_EXCLUDED(crit_);
+ RTC_LOCKS_EXCLUDED(mutex_);
private:
Clock* const clock_;
- // Clears with |crit_| taken.
- void ClearInternal() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
+ // Clears with |mutex_| taken.
+ void ClearInternal() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Tries to expand the buffer.
- bool ExpandBufferSize() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
+ bool ExpandBufferSize() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Test if all previous packets has arrived for the given sequence number.
bool PotentialNewFrame(uint16_t seq_num) const
- RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Test if all packets of a frame has arrived, and if so, returns packets to
// create frames.
std::vector<std::unique_ptr<Packet>> FindFrames(uint16_t seq_num)
- RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void UpdateMissingPackets(uint16_t seq_num)
- RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
- rtc::CriticalSection crit_;
+ mutable Mutex mutex_;
// buffer_.size() and max_size_ must always be a power of two.
const size_t max_size_;
// The fist sequence number currently in the buffer.
- uint16_t first_seq_num_ RTC_GUARDED_BY(crit_);
+ uint16_t first_seq_num_ RTC_GUARDED_BY(mutex_);
// If the packet buffer has received its first packet.
- bool first_packet_received_ RTC_GUARDED_BY(crit_);
+ bool first_packet_received_ RTC_GUARDED_BY(mutex_);
// If the buffer is cleared to |first_seq_num_|.
- bool is_cleared_to_first_seq_num_ RTC_GUARDED_BY(crit_);
+ bool is_cleared_to_first_seq_num_ RTC_GUARDED_BY(mutex_);
// Buffer that holds the the inserted packets and information needed to
// determine continuity between them.
- std::vector<std::unique_ptr<Packet>> buffer_ RTC_GUARDED_BY(crit_);
+ std::vector<std::unique_ptr<Packet>> buffer_ RTC_GUARDED_BY(mutex_);
// Timestamp of the last received packet/keyframe packet.
- absl::optional<int64_t> last_received_packet_ms_ RTC_GUARDED_BY(crit_);
+ absl::optional<int64_t> last_received_packet_ms_ RTC_GUARDED_BY(mutex_);
absl::optional<int64_t> last_received_keyframe_packet_ms_
- RTC_GUARDED_BY(crit_);
+ RTC_GUARDED_BY(mutex_);
absl::optional<uint32_t> last_received_keyframe_rtp_timestamp_
- RTC_GUARDED_BY(crit_);
+ RTC_GUARDED_BY(mutex_);
- absl::optional<uint16_t> newest_inserted_seq_num_ RTC_GUARDED_BY(crit_);
+ absl::optional<uint16_t> newest_inserted_seq_num_ RTC_GUARDED_BY(mutex_);
std::set<uint16_t, DescendingSeqNumComp<uint16_t>> missing_packets_
- RTC_GUARDED_BY(crit_);
+ RTC_GUARDED_BY(mutex_);
// Indicates if we should require SPS, PPS, and IDR for a particular
// RTP timestamp to treat the corresponding frame as a keyframe.