Chromium Code Reviews| Index: base/synchronization/atomic_flag_unittest.cc |
| diff --git a/base/synchronization/atomic_flag_unittest.cc b/base/synchronization/atomic_flag_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c881d5b40c71f01ba7d2cc79c68ee33fe9c68d5a |
| --- /dev/null |
| +++ b/base/synchronization/atomic_flag_unittest.cc |
| @@ -0,0 +1,83 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +// Tests of AtomicFlag class. |
| + |
| +#include "base/synchronization/atomic_flag.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/single_thread_task_runner.h" |
| +#include "base/threading/thread.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace base { |
| + |
| +namespace { |
| + |
| +void CancelHelper(AtomicFlag* flag) { |
|
danakj
2016/07/20 19:21:01
rename to SetFlag or something?
fdoray
2016/07/21 13:08:33
Done.
|
| + ASSERT_TRUE(flag); |
| +#if GTEST_HAS_DEATH_TEST |
| + ASSERT_DEBUG_DEATH(flag->Set(), ""); |
|
fdoray
2016/07/20 16:24:11
TODO: Use EXPECT_DCHECK_DEATH once https://coderev
|
| +#endif |
| +} |
| + |
| +void ExpectIsNotSet(AtomicFlag* flag) { |
| + ASSERT_TRUE(flag); |
| + EXPECT_FALSE(flag->IsSet()); |
| +} |
| + |
| +void ExpectIsSet(AtomicFlag* flag) { |
| + ASSERT_TRUE(flag); |
| + EXPECT_TRUE(flag->IsSet()); |
| +} |
| + |
| +} // namespace |
| + |
| +TEST(AtomicFlagTest, SimpleSingleThreadedTest) { |
| + AtomicFlag flag; |
| + ASSERT_FALSE(flag.IsSet()); |
| + flag.Set(); |
| + ASSERT_TRUE(flag.IsSet()); |
| +} |
| + |
| +TEST(AtomicFlagTest, DoubleSetTest) { |
| + AtomicFlag flag; |
| + ASSERT_FALSE(flag.IsSet()); |
| + flag.Set(); |
| + ASSERT_TRUE(flag.IsSet()); |
| + flag.Set(); |
| + ASSERT_TRUE(flag.IsSet()); |
| +} |
| + |
| +TEST(AtomicFlagTest, ReadFromDifferentThread) { |
| + AtomicFlag flag; |
| + |
| + { |
| + Thread t("AtomicFlagTest.ReadFromDifferentThread.ExpectIsNotSetThread"); |
| + ASSERT_TRUE(t.Start()); |
| + t.task_runner()->PostTask(FROM_HERE, Bind(&ExpectIsNotSet, &flag)); |
| + } |
| + |
| + flag.Set(); |
| + |
| + { |
| + Thread t("AtomicFlagTest.ReadFromDifferentThread.ExpectIsSetThread"); |
| + ASSERT_TRUE(t.Start()); |
| + t.task_runner()->PostTask(FROM_HERE, Bind(&ExpectIsSet, &flag)); |
|
danakj
2016/07/20 19:21:01
post task is a memory barrier so this test is kind
fdoray
2016/07/21 13:08:33
sgtm
gab
2016/07/21 13:27:12
True, then maybe sleep here for say 10ms before ca
fdoray
2016/07/21 14:05:30
sgtm.
I'm still a little bit worried that Sleep,
gab
2016/07/21 14:16:04
I doubt Sleep and Yield result in memory barriers.
fdoray
2016/07/21 15:50:02
Shouldn't the memory be synchronized when the thre
gab
2016/07/21 15:56:42
I don't think memory *has* to be synchronized when
|
| + } |
| +} |
| + |
| +TEST(AtomicFlagTest, SetOnDifferentThreadDeathTest) { |
| + // Checks that Set() can't be called from any other thread. |
| + // AtomicFlag should die on a DCHECK if Set() is called from |
| + // other thread. |
| + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
| + Thread t("AtomicFlagTest.SetOnDifferentThreadDeathTest"); |
| + ASSERT_TRUE(t.Start()); |
| + |
| + AtomicFlag flag; |
| + t.task_runner()->PostTask(FROM_HERE, Bind(&CancelHelper, &flag)); |
| +} |
| + |
| +} // namespace base |