Implement Atomic32 using C++11's std::atomic

Chromoting is planning to bump up the iOS deployment target to 10.0
before but is blocked by WebRTC because it uses deprecated OSAtomic*
APIs.

This CL replaces the platform specific Atomic32 implementation and uses
C++11's std::atomic instead.

Bug: webrtc:8413
Change-Id: Icbd29bb92eec60066589bbabf53e0d50df2f9b0d
Reviewed-on: https://webrtc-review.googlesource.com/12740
Commit-Queue: Yuwei Huang <yuweih@google.com>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20376}
This commit is contained in:
Yuwei Huang
2017-10-20 15:47:42 -07:00
committed by Commit Bot
parent f2662f08e5
commit 160c02089e
5 changed files with 20 additions and 142 deletions

View File

@ -27,7 +27,7 @@ rtc_static_library("system_wrappers") {
"include/sleep.h",
"include/timestamp_extrapolator.h",
"source/aligned_malloc.cc",
"source/atomic32_win.cc",
"source/atomic32.cc",
"source/clock.cc",
"source/cpu_features.cc",
"source/cpu_info.cc",
@ -76,13 +76,8 @@ rtc_static_library("system_wrappers") {
libs += [ "rt" ]
}
if (is_linux || is_android) {
sources += [ "source/atomic32_non_darwin_unix.cc" ]
}
if (is_ios || is_mac) {
defines += [ "WEBRTC_THREAD_RR" ]
sources += [ "source/atomic32_darwin.cc" ]
}
# TODO(jschuh): Bug 1348: fix this warning.

View File

@ -15,6 +15,8 @@
#ifndef SYSTEM_WRAPPERS_INCLUDE_ATOMIC32_H_
#define SYSTEM_WRAPPERS_INCLUDE_ATOMIC32_H_
#include <atomic>
#include <stddef.h>
#include "common_types.h" // NOLINT(build/include)
@ -22,6 +24,9 @@
namespace webrtc {
// DEPRECATED: Please use std::atomic<int32_t> instead.
// TODO(yuweih): Replace Atomic32 uses with std::atomic<int32_t> and remove this
// class. (bugs.webrtc.org/8428)
// 32 bit atomic variable. Note that this class relies on the compiler to
// align the 32 bit value correctly (on a 32 bit boundary), so as long as you're
// not doing things like reinterpret_cast over some custom allocated memory
@ -41,19 +46,12 @@ class Atomic32 {
// Sets the value atomically to new_value if the value equals compare value.
// The function returns true if the exchange happened.
bool CompareExchange(int32_t new_value, int32_t compare_value);
int32_t Value() {
return *this += 0;
}
int32_t Value() const;
private:
// Checks if |_value| is 32bit aligned.
inline bool Is32bitAligned() const {
return (reinterpret_cast<ptrdiff_t>(&value_) & 3) == 0;
}
RTC_DISALLOW_COPY_AND_ASSIGN(Atomic32);
int32_t value_;
std::atomic<int32_t> value_;
};
} // namespace webrtc

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2017 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
@ -11,39 +11,37 @@
#include "system_wrappers/include/atomic32.h"
#include <assert.h>
#include <libkern/OSAtomic.h>
#include <stdlib.h>
#include "common_types.h" // NOLINT(build/include)
namespace webrtc {
Atomic32::Atomic32(int32_t initial_value)
: value_(initial_value) {
assert(Is32bitAligned());
}
Atomic32::Atomic32(int32_t initial_value) : value_(initial_value) {}
Atomic32::~Atomic32() {
}
Atomic32::~Atomic32() {}
int32_t Atomic32::operator++() {
return OSAtomicIncrement32Barrier(&value_);
return ++value_;
}
int32_t Atomic32::operator--() {
return OSAtomicDecrement32Barrier(&value_);
return --value_;
}
int32_t Atomic32::operator+=(int32_t value) {
return OSAtomicAdd32Barrier(value, &value_);
return value_ += value;
}
int32_t Atomic32::operator-=(int32_t value) {
return OSAtomicAdd32Barrier(-value, &value_);
return value_ -= value;
}
bool Atomic32::CompareExchange(int32_t new_value, int32_t compare_value) {
return OSAtomicCompareAndSwap32Barrier(compare_value, new_value, &value_);
return value_.compare_exchange_strong(compare_value, new_value);
}
int32_t Atomic32::Value() const {
return value_.load();
}
} // namespace webrtc

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 2012 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.
*/
#include "system_wrappers/include/atomic32.h"
#include <assert.h>
#include <inttypes.h>
#include <malloc.h>
#include "common_types.h" // NOLINT(build/include)
namespace webrtc {
Atomic32::Atomic32(int32_t initial_value)
: value_(initial_value) {
assert(Is32bitAligned());
}
Atomic32::~Atomic32() {
}
int32_t Atomic32::operator++() {
return __sync_fetch_and_add(&value_, 1) + 1;
}
int32_t Atomic32::operator--() {
return __sync_fetch_and_sub(&value_, 1) - 1;
}
int32_t Atomic32::operator+=(int32_t value) {
int32_t return_value = __sync_fetch_and_add(&value_, value);
return_value += value;
return return_value;
}
int32_t Atomic32::operator-=(int32_t value) {
int32_t return_value = __sync_fetch_and_sub(&value_, value);
return_value -= value;
return return_value;
}
bool Atomic32::CompareExchange(int32_t new_value, int32_t compare_value) {
return __sync_bool_compare_and_swap(&value_, compare_value, new_value);
}
} // namespace webrtc

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2012 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.
*/
#include "system_wrappers/include/atomic32.h"
#include <assert.h>
#include <windows.h>
#include "common_types.h" // NOLINT(build/include)
namespace webrtc {
Atomic32::Atomic32(int32_t initial_value)
: value_(initial_value) {
static_assert(sizeof(value_) == sizeof(LONG),
"counter variable is the expected size");
assert(Is32bitAligned());
}
Atomic32::~Atomic32() {
}
int32_t Atomic32::operator++() {
return static_cast<int32_t>(InterlockedIncrement(
reinterpret_cast<volatile LONG*>(&value_)));
}
int32_t Atomic32::operator--() {
return static_cast<int32_t>(InterlockedDecrement(
reinterpret_cast<volatile LONG*>(&value_)));
}
int32_t Atomic32::operator+=(int32_t value) {
return InterlockedExchangeAdd(reinterpret_cast<volatile LONG*>(&value_),
value);
}
int32_t Atomic32::operator-=(int32_t value) {
return InterlockedExchangeAdd(reinterpret_cast<volatile LONG*>(&value_),
-value);
}
bool Atomic32::CompareExchange(int32_t new_value, int32_t compare_value) {
const LONG old_value = InterlockedCompareExchange(
reinterpret_cast<volatile LONG*>(&value_),
new_value,
compare_value);
// If the old value and the compare value is the same an exchange happened.
return (old_value == compare_value);
}
} // namespace webrtc