26 #include <glog/logging.h> 36 static const int kMaxReaders = 50;
37 static std::atomic<bool> stopThread;
38 using namespace folly;
40 template <
typename RWSpinLockT>
42 typedef RWSpinLockT RWSpinLockType;
45 typedef testing::Types<
47 #ifdef RW_SPINLOCK_USE_X86_INTRINSIC_ 49 RWTicketSpinLockT<32, true>,
50 RWTicketSpinLockT<32, false>,
51 RWTicketSpinLockT<64, true>,
52 RWTicketSpinLockT<64, false>
59 template <
typename RWSpinLockType>
60 static void run(RWSpinLockType*
lock) {
63 while (!stopThread.load(std::memory_order_acquire)) {
64 if (rand() % 10 == 0) {
65 typename RWSpinLockType::WriteHolder
guard(lock);
68 typename RWSpinLockType::ReadHolder
guard(lock);
75 TYPED_TEST(RWSpinLockTest, Writer_Wait_Readers) {
76 typedef typename TestFixture::RWSpinLockType RWSpinLockType;
79 for (
int i = 0;
i < kMaxReaders; ++
i) {
84 for (
int i = 0;
i < kMaxReaders; ++
i) {
92 TYPED_TEST(RWSpinLockTest, Readers_Wait_Writer) {
93 typedef typename TestFixture::RWSpinLockType RWSpinLockType;
98 for (
int i = 0;
i < kMaxReaders; ++
i) {
102 l.unlock_and_lock_shared();
103 for (
int i = 0;
i < kMaxReaders - 1; ++
i) {
108 TYPED_TEST(RWSpinLockTest, Writer_Wait_Writer) {
109 typedef typename TestFixture::RWSpinLockType RWSpinLockType;
121 typedef typename TestFixture::RWSpinLockType RWSpinLockType;
125 typename RWSpinLockType::ReadHolder
guard(&l);
138 typedef typename TestFixture::RWSpinLockType RWSpinLockType;
141 typename RWSpinLockType::WriteHolder
guard(&l);
153 typedef typename TestFixture::RWSpinLockType RWSpinLockType;
155 srand(
time(
nullptr));
157 std::vector<std::thread>
threads;
158 for (
int i = 0;
i < FLAGS_num_threads; ++
i) {
159 threads.push_back(std::thread(&run<RWSpinLockType>, &l));
163 stopThread.store(
true, std::memory_order_release);
165 for (
auto&
t : threads) {
172 TEST(RWSpinLock, lock_unlock_tests) {
193 TEST(RWSpinLock, concurrent_holder_test) {
194 srand(
time(
nullptr));
197 std::atomic<int64_t> reads(0);
198 std::atomic<int64_t> writes(0);
199 std::atomic<int64_t> upgrades(0);
200 std::atomic<bool>
stop(
false);
203 while (!
stop.load(std::memory_order_acquire)) {
208 writes.fetch_add(1, std::memory_order_acq_rel);
216 upgrades.fetch_add(1, std::memory_order_acq_rel);
219 reads.fetch_add(1, std::memory_order_acq_rel);
224 std::vector<std::thread>
threads;
225 for (
int i = 0;
i < FLAGS_num_threads; ++
i) {
226 threads.push_back(std::thread(go));
230 stop.store(
true, std::memory_order_release);
232 for (
auto&
t : threads) {
236 LOG(
INFO) <<
"reads: " << reads.load(std::memory_order_acquire)
237 <<
"; writes: " << writes.load(std::memory_order_acquire)
238 <<
"; upgrades: " << upgrades.load(std::memory_order_acquire);
void unlock_upgrade_and_lock_shared()
void unlock_and_lock_upgrade()
#define EXPECT_EQ(val1, val2)
Future< Unit > sleep(Duration dur, Timekeeper *tk)
constexpr detail::Map< Move > move
TYPED_TEST_CASE(SynchronizedTest, SynchronizedTestTypes)
—— Concurrent Priority Queue Implementation ——
std::vector< std::thread::id > threads
static void run(EventBaseManager *ebm, EventBase *eb, folly::Baton<> *stop, const StringPiece &name)
TYPED_TEST(SynchronizedTest, Basic)
GuardImpl guard(ErrorHandler &&handler)
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
DEFINE_int32(num_threads, 8,"num threads")
#define EXPECT_TRUE(condition)
#define EXPECT_FALSE(condition)
TEST(SequencedExecutor, CPUThreadPoolExecutor)
std::chrono::nanoseconds time()