Refactor base/atomic_sequence_num
This CL refactors AtomicSequenceNumber to adopt <atomic>, and removes
StaticAtomicSequenceNumber, which is no longer needed after C++11.
Change-Id: Ia061cd4af76bbd630dc6fbc0e791b11013b0cd67
Reviewed-on: https://chromium-review.googlesource.com/566979
Reviewed-by: Daniel Cheng <[email protected]>
Commit-Queue: Taiju Tsuiki <[email protected]>
Cr-Commit-Position: refs/heads/master@{#485908}
diff --git a/base/atomic_sequence_num.h b/base/atomic_sequence_num.h
index 59b0d25..3e7e95e5 100644
--- a/base/atomic_sequence_num.h
+++ b/base/atomic_sequence_num.h
@@ -5,56 +5,33 @@
#ifndef BASE_ATOMIC_SEQUENCE_NUM_H_
#define BASE_ATOMIC_SEQUENCE_NUM_H_
-#include "base/atomicops.h"
+#include <atomic>
+
#include "base/macros.h"
namespace base {
-class AtomicSequenceNumber;
-
-// Static (POD) AtomicSequenceNumber that MUST be used in global scope (or
-// non-function scope) ONLY. This implementation does not generate any static
-// initializer. Note that it does not implement any constructor which means
-// that its fields are not initialized except when it is stored in the global
-// data section (.data in ELF). If you want to allocate an atomic sequence
-// number on the stack (or heap), please use the AtomicSequenceNumber class
-// declared below.
-class StaticAtomicSequenceNumber {
- public:
- inline int GetNext() {
- return static_cast<int>(
- base::subtle::NoBarrier_AtomicIncrement(&seq_, 1) - 1);
- }
-
- private:
- friend class AtomicSequenceNumber;
-
- inline void Reset() {
- base::subtle::Release_Store(&seq_, 0);
- }
-
- base::subtle::Atomic32 seq_;
-};
-
-// AtomicSequenceNumber that can be stored and used safely (i.e. its fields are
-// always initialized as opposed to StaticAtomicSequenceNumber declared above).
-// Please use StaticAtomicSequenceNumber if you want to declare an atomic
-// sequence number in the global scope.
+// AtomicSequenceNumber is a thread safe increasing sequence number generator.
+// Its constructor doesn't emit a static initializer, so it's safe to use as a
+// global variable or static member.
class AtomicSequenceNumber {
public:
- AtomicSequenceNumber() {
- seq_.Reset();
- }
+ constexpr AtomicSequenceNumber() {}
- inline int GetNext() {
- return seq_.GetNext();
- }
+ // Returns an increasing sequence number starts from 0 for each call.
+ // This function can be called from any thread without data race.
+ inline int GetNext() { return seq_.fetch_add(1, std::memory_order_relaxed); }
private:
- StaticAtomicSequenceNumber seq_;
+ std::atomic_int seq_{0};
+
DISALLOW_COPY_AND_ASSIGN(AtomicSequenceNumber);
};
+// TODO(tzik): Replace all usage of StaticAtomicSequenceNumber with
+// AtomicSequenceNumber, and remove this alias.
+using StaticAtomicSequenceNumber = AtomicSequenceNumber;
+
} // namespace base
#endif // BASE_ATOMIC_SEQUENCE_NUM_H_