Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(466)

Unified Diff: webrtc/modules/audio_processing/swap_queue.h

Issue 1398473004: Changed queue implementation to the proposed vector-based solution. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@lock_unittest_CL
Patch Set: Changes in response to reviewer comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_processing/swap_queue.h
diff --git a/webrtc/modules/audio_processing/swap_queue.h b/webrtc/modules/audio_processing/swap_queue.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff63c669a6286568c771ff4ed535ac9526637df4
--- /dev/null
+++ b/webrtc/modules/audio_processing/swap_queue.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_
+#define WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_
kwiberg-webrtc 2015/10/12 14:05:48 The include guard name needs updating.
peah-webrtc 2015/10/13 11:56:13 Done.
+
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/criticalsection.h"
+
+namespace webrtc {
+
+// This class is to be used as a one-way queue where data is
kwiberg-webrtc 2015/10/12 14:05:48 It actually *is* a one-way queue.
peah-webrtc 2015/10/13 11:56:13 Done.
+// written from one end and read from the other end.
+// It is safe to access the class concurrently from multiple threads.
The Sun (google.com) 2015/10/13 07:53:05 Will git cl format fix the alignment of comment li
peah-webrtc 2015/10/13 11:56:13 You mean whether multiline comments are rearranged
the sun 2015/10/13 12:34:27 yes
peah-webrtc 2015/10/26 08:56:56 Acknowledged.
+// The queueable objects must all be swappable.
+//
+// When T is a vector, one way of us using this class is by leveraging that
The Sun (google.com) 2015/10/13 07:53:05 What you describe is the general intention of this
peah-webrtc 2015/10/13 11:56:13 I fully agree. I revised the description, and adde
+// the vector returned (via a swap) when doing an Insert can be reused if
+// the queue is properly initialized. For instance, if the queue is initialized
+// with N elements sized vectors, and the vectors passed to the Insert and
+// Remove methods also are always N elements long, the vector returned from
+// the Insert method always have a size of N, allowing for a cheap scheme of
+// avoiding vector reallocations.
+template <typename T>
+class SwapQueue {
kwiberg-webrtc 2015/10/12 14:05:48 It might be a good idea to reflect the threadsafen
The Sun (google.com) 2015/10/13 07:53:05 +1 -1 I think that is a good idea assuming we are
kwiberg-webrtc 2015/10/13 09:59:53 OK. Then I suggest to err on the side of brevity.
peah-webrtc 2015/10/13 11:56:12 How about omitting threadsafety in the name, but o
kwiberg-webrtc 2015/10/13 12:09:07 Dynamically taking locks or not would make the cod
peah-webrtc 2015/10/26 08:56:56 Acknowledged.
+ public:
+ // Creates a queue of size size.
kwiberg-webrtc 2015/10/12 14:05:48 Document that this fills the queue with the specif
peah-webrtc 2015/10/13 11:56:13 Done.
+ explicit SwapQueue(size_t size) { queue_.resize(size); }
kwiberg-webrtc 2015/10/12 14:05:48 explicit SwapQueue(size_t size) : queue_(size) {}
peah-webrtc 2015/10/13 11:56:13 Done.
+
+ // Creates a queue of size size and initializes each element
+ // to have the same size and content of initializer (useful to
+ // ensure a certain initial size when T is a vector).
+ explicit SwapQueue<T>(size_t size, const T& initializer)
+ : SwapQueue<T>(size) {
The Sun (google.com) 2015/10/13 07:53:05 : queue_(size, initializer) { i.e. don't default-
peah-webrtc 2015/10/13 11:56:13 Done.
+ queue_ = std::vector<T>(size, initializer);
+ }
kwiberg-webrtc 2015/10/12 14:05:48 "explicit" is only needed for one-argument constru
peah-webrtc 2015/10/13 11:56:13 I removed this constructor.
the sun 2015/10/13 12:34:26 But why? Supplying a prototype object which is cop
kwiberg-webrtc 2015/10/13 14:08:36 Sure, it might be a convenient shortcut.
+
+ // Ensures that the internal queue elements of type vector
+ // are formed as in the supplied empty slots input
kwiberg-webrtc 2015/10/12 14:05:48 Maybe just // Create a queue with "empty" Ts fr
peah-webrtc 2015/10/13 11:56:13 Excellent suggestion.
peah-webrtc 2015/10/13 11:56:13 Done.
+ // TODO(peah): Change to std::vector<T>&& when we have a C++11
+ // standard library.
kwiberg-webrtc 2015/10/12 15:39:10 Actually, I realized on the way home that we only
peah-webrtc 2015/10/13 11:56:12 Nice! But I get a cl upload warning that the below
+ //
+ // If using the above described scheme that ensures that all elements in the
+ // queue are of the same size, this is achieved if the following constructor
+ // is used with an input of vectors having the same size.
kwiberg-webrtc 2015/10/12 14:05:48 You repeat this several times. Maybe just once, in
The Sun (google.com) 2015/10/13 07:53:05 It is confusing that you talk about "input of vect
kwiberg-webrtc 2015/10/13 09:59:53 We don't. std::vector is less convenient than it c
peah-webrtc 2015/10/13 11:56:13 I made an attempt to do that. Could you please hav
peah-webrtc 2015/10/13 11:56:13 I agree about repetition, and I removed that part.
+ explicit SwapQueue(std::vector<T>* empty_slots) {
+ RTC_CHECK_GE(empty_slots->size(), 1u);
+ using std::swap;
The Sun (google.com) 2015/10/13 07:53:05 Why not just do std::swap on the line below?
kwiberg-webrtc 2015/10/13 09:59:53 Because the author of T might have defined a swap(
peah-webrtc 2015/10/13 11:56:13 I kept it as it is for now. Please let me know if
peah-webrtc 2015/10/13 11:56:13 Acknowledged.
the sun 2015/10/13 12:34:27 Great! Thanks for the explanation.
+ swap(queue_, *empty_slots);
+ }
+
+ // Resets the queue to have zero content.
+ void Clear() {
+ rtc::CritScope cs(&crit_queue_);
+ last_write_index_ = 0;
+ last_read_index_ = 0;
+ num_elements_ = 0;
+ }
+
+ // Inserts a chunk of data into the queue in a thread safe manner.
kwiberg-webrtc 2015/10/12 14:05:48 Document thread safety once, in the class descript
peah-webrtc 2015/10/13 11:56:12 Done.
+ // The input is swapped with the next available value of type T
+ // present in the queue.
+ // Returns false if the queue is full, and true if not.
kwiberg-webrtc 2015/10/12 14:05:48 Document that the operation is a no-op iff it retu
peah-webrtc 2015/10/13 11:56:13 Done.
+ //
+ // Note that in the case of T being a vector, if using the above described
The Sun (google.com) 2015/10/13 07:53:05 Please remove these comments. Too much text will m
peah-webrtc 2015/10/13 11:56:13 Done.
+ // scheme to ensure that all elements in the queue are of the same size, the
+ // resulting content in input after the swap also has the same size.
+ bool Insert(T* input) {
+ rtc::CritScope cs(&crit_queue_);
+
+ // Early return if the queue is full.
+ if (num_elements_ == queue_.size())
+ return false;
+
+ last_write_index_ =
+ (last_write_index_ < (queue_.size() - 1) ? last_write_index_ + 1 : 0);
+
+ using std::swap;
+ swap(*input, queue_[last_write_index_]);
+
+ num_elements_++;
+ return true;
+ }
+
+ // Removes a chunk of data from the queue in a thread safe manner.
+ // The queue element is swapped with the previous content of output.
+ // Returns false if the queue is empty, and true if not.
kwiberg-webrtc 2015/10/12 14:05:48 Same as above: document thread safety once, and sa
peah-webrtc 2015/10/13 11:56:13 Done.
+ //
+ // Note that in the case of T being a vector, if using the above described
+ // scheme to ensure that all elements in the queue are of the same size,
+ // it is important to ensure that the initial content of output has the
+ // same size as the content in the queue.
+ bool Remove(T* output) {
+ rtc::CritScope cs(&crit_queue_);
+
+ // Early return for empty queue.
+ if (num_elements_ == 0)
+ return false;
+
+ last_read_index_ =
+ (last_read_index_ < (queue_.size() - 1) ? last_read_index_ + 1 : 0);
The Sun (google.com) 2015/10/13 07:53:05 I'd rather you last_read_index_++; if (last_read_
peah-webrtc 2015/10/13 11:56:13 Done.
+ output->swap(queue_[last_read_index_]);
kwiberg-webrtc 2015/10/12 14:05:48 Use the same swap idiom as above.
peah-webrtc 2015/10/13 11:56:13 Done.
+
+ num_elements_--;
+ return true;
+ }
+
+ private:
+ std::vector<T> queue_ GUARDED_BY(crit_queue_);
+ size_t last_write_index_ GUARDED_BY(crit_queue_) = 0;
+ size_t last_read_index_ GUARDED_BY(crit_queue_) = 0;
+ size_t num_elements_ GUARDED_BY(crit_queue_) = 0;
kwiberg-webrtc 2015/10/12 14:05:48 Document the invariants: queue_.size() never chang
peah-webrtc 2015/10/13 11:56:13 Done.
peah-webrtc 2015/10/13 11:56:13 Good point! I changed to using next, and added the
+ rtc::CriticalSection crit_queue_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(SwapQueue);
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_AUDIO_PROCESSING_SWAPPED_NONBLOCKING_QUEUE_H_
« no previous file with comments | « webrtc/modules/audio_processing/audio_processing.gypi ('k') | webrtc/modules/audio_processing/swap_queue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698