/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2011-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
// @author: Andrei Alexandrescu (aalexandre)
// Test bed for folly/Synchronized.h
+#include <folly/Synchronized.h>
#include <folly/LockTraitsBoost.h>
#include <folly/Portability.h>
-#include <folly/RWSpinLock.h>
#include <folly/SharedMutex.h>
#include <folly/SpinLock.h>
-#include <folly/Synchronized.h>
-#include <folly/test/SynchronizedTestLib.h>
#include <folly/portability/GTest.h>
+#include <folly/synchronization/RWSpinLock.h>
+#include <folly/test/SynchronizedTestLib.h>
using namespace folly::sync_tests;
testConstCopy<TypeParam>();
}
+TYPED_TEST(SynchronizedTest, InPlaceConstruction) {
+ testInPlaceConstruction<TypeParam>();
+}
+
+TYPED_TEST(SynchronizedTest, Exchange) {
+ testExchange<TypeParam>();
+}
+
template <class Mutex>
class SynchronizedTimedTest : public testing::Test {};
testTimedSynchronizedWithConst<TypeParam>();
}
-TYPED_TEST(SynchronizedTest, InPlaceConstruction) {
- testInPlaceConstruction<TypeParam>();
-}
-
using CountPair = std::pair<int, int>;
// This class is specialized only to be uesed in SynchronizedLockTest
class FakeMutex {
}
};
-// Single level of SYNCHRONIZED and UNSYNCHRONIZED, although nested test are
-// super set of it, it is possible single level test passes while nested tests
-// fail
-TEST_F(SynchronizedLockTest, SyncUnSync) {
- folly::Synchronized<std::vector<int>, FakeMutex> obj;
- EXPECT_EQ((CountPair{0, 0}), FakeMutex::getLockUnlockCount());
- SYNCHRONIZED(obj) {
- EXPECT_EQ((CountPair{1, 0}), FakeMutex::getLockUnlockCount());
- UNSYNCHRONIZED(obj) {
- EXPECT_EQ((CountPair{1, 1}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{2, 1}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{2, 2}), FakeMutex::getLockUnlockCount());
-}
-
-// Nested SYNCHRONIZED UNSYNCHRONIZED test, 2 levels of synchronization
-TEST_F(SynchronizedLockTest, NestedSyncUnSync) {
- folly::Synchronized<std::vector<int>, FakeMutex> obj;
- EXPECT_EQ((CountPair{0, 0}), FakeMutex::getLockUnlockCount());
- SYNCHRONIZED(objCopy, obj) {
- EXPECT_EQ((CountPair{1, 0}), FakeMutex::getLockUnlockCount());
- SYNCHRONIZED(obj) {
- EXPECT_EQ((CountPair{2, 0}), FakeMutex::getLockUnlockCount());
- // Note: UNSYNCHRONIZED has always been kind of broken here.
- // The input parameter is ignored (other than to overwrite what the input
- // variable name refers to), and it unlocks the most object acquired in
- // the most recent SYNCHRONIZED scope.
- UNSYNCHRONIZED(obj) {
- EXPECT_EQ((CountPair{2, 1}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{3, 1}), FakeMutex::getLockUnlockCount());
- UNSYNCHRONIZED(obj) {
- EXPECT_EQ((CountPair{3, 2}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{4, 2}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{4, 3}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{4, 4}), FakeMutex::getLockUnlockCount());
-}
-
-// Different nesting behavior, UNSYNCHRONIZED called on different depth of
-// SYNCHRONIZED
-TEST_F(SynchronizedLockTest, NestedSyncUnSync2) {
- folly::Synchronized<std::vector<int>, FakeMutex> obj;
- EXPECT_EQ((CountPair{0, 0}), FakeMutex::getLockUnlockCount());
- SYNCHRONIZED(objCopy, obj) {
- EXPECT_EQ((CountPair{1, 0}), FakeMutex::getLockUnlockCount());
- SYNCHRONIZED(obj) {
- EXPECT_EQ((CountPair{2, 0}), FakeMutex::getLockUnlockCount());
- UNSYNCHRONIZED(obj) {
- EXPECT_EQ((CountPair{2, 1}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{3, 1}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{3, 2}), FakeMutex::getLockUnlockCount());
- UNSYNCHRONIZED(obj) {
- EXPECT_EQ((CountPair{3, 3}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{4, 3}), FakeMutex::getLockUnlockCount());
- }
- EXPECT_EQ((CountPair{4, 4}), FakeMutex::getLockUnlockCount());
-}
-
TEST_F(SynchronizedLockTest, TestCopyConstructibleValues) {
struct NonCopyConstructible {
NonCopyConstructible(const NonCopyConstructible&) = delete;