Fix pointer compare-and-swap on Windows.

Incorrect argument order, also added unittest which should've been there
in the first place.

Also renames AtomicLoadPtr to AcquireLoadPtr to match non-ptr version.

BUG=
R=tommi@webrtc.org

Review URL: https://codereview.webrtc.org/1537923003 .

Cr-Commit-Position: refs/heads/master@{#11086}
This commit is contained in:
Peter Boström
2015-12-18 17:00:25 +01:00
parent c1cd566cc6
commit 455a252453
3 changed files with 27 additions and 4 deletions

View File

@ -44,13 +44,13 @@ class AtomicOps {
}
// Pointer variants.
template <typename T>
static T* AtomicLoadPtr(T* volatile* ptr) {
static T* AcquireLoadPtr(T* volatile* ptr) {
return *ptr;
}
template <typename T>
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
return static_cast<T*>(::InterlockedCompareExchangePointer(
reinterpret_cast<PVOID volatile*>(ptr), old_value, new_value));
reinterpret_cast<PVOID volatile*>(ptr), new_value, old_value));
}
#else
static int Increment(volatile int* i) {
@ -70,7 +70,7 @@ class AtomicOps {
}
// Pointer variants.
template <typename T>
static T* AtomicLoadPtr(T* volatile* ptr) {
static T* AcquireLoadPtr(T* volatile* ptr) {
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
}
template <typename T>

View File

@ -14,6 +14,7 @@
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/event.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/scopedptrcollection.h"
#include "webrtc/base/thread.h"
#include "webrtc/test/testsupport/gtest_disable.h"
@ -220,6 +221,28 @@ TEST(AtomicOpsTest, Simple) {
EXPECT_EQ(0, value);
}
TEST(AtomicOpsTest, SimplePtr) {
class Foo {};
Foo* volatile foo = nullptr;
scoped_ptr<Foo> a(new Foo());
scoped_ptr<Foo> b(new Foo());
// Reading the initial value should work as expected.
EXPECT_TRUE(rtc::AtomicOps::AcquireLoadPtr(&foo) == nullptr);
// Setting using compare and swap should work.
EXPECT_TRUE(rtc::AtomicOps::CompareAndSwapPtr(
&foo, static_cast<Foo*>(nullptr), a.get()) == nullptr);
EXPECT_TRUE(rtc::AtomicOps::AcquireLoadPtr(&foo) == a.get());
// Setting another value but with the wrong previous pointer should fail
// (remain a).
EXPECT_TRUE(rtc::AtomicOps::CompareAndSwapPtr(
&foo, static_cast<Foo*>(nullptr), b.get()) == a.get());
EXPECT_TRUE(rtc::AtomicOps::AcquireLoadPtr(&foo) == a.get());
// Replacing a with b should work.
EXPECT_TRUE(rtc::AtomicOps::CompareAndSwapPtr(&foo, a.get(), b.get()) ==
a.get());
EXPECT_TRUE(rtc::AtomicOps::AcquireLoadPtr(&foo) == b.get());
}
TEST(AtomicOpsTest, Increment) {
// Create and start lots of threads.
AtomicOpRunner<IncrementOp, UniqueValueVerifier> runner(0);

View File

@ -257,7 +257,7 @@ void StopInternalCapture() {
void ShutdownInternalTracer() {
StopInternalCapture();
EventLogger* old_logger = rtc::AtomicOps::AtomicLoadPtr(&g_event_logger);
EventLogger* old_logger = rtc::AtomicOps::AcquireLoadPtr(&g_event_logger);
RTC_DCHECK(old_logger);
RTC_CHECK(rtc::AtomicOps::CompareAndSwapPtr(
&g_event_logger, old_logger,