/* * Basic function tests. */ void TEST_basic_1() { glog_info(MSG("basic_1"), MSG("test lock function")); constexpr int thread_cnt = 32; constexpr int add_per_thread = 100000; int target_counter = 0; Spinlock lock; std::vector<std::thread> threads; for (int idx = 0, cnt = thread_cnt; idx < cnt; ++idx) { threads.push_back(std::move(std::thread{[&](){ for (int idx2 = 0, cnt2 = add_per_thread; idx2 < cnt2; ++idx2) { lock.lock(); target_counter += 1; lock.unlock(); } }})); } for (int idx = 0, cnt = thread_cnt; idx < cnt; ++idx) { threads[idx].join(); } // Verify. if (thread_cnt * add_per_thread != target_counter) { glog_fatal(MSG("err counter"), KEYVAL(target_counter), KEYVAL(thread_cnt), KEYVAL(add_per_thread)); } }
/******************* FUNCTION *********************/ TEST(TestSpinlock, correctness) { Spinlock lock; int sum = 0; int nbthread = 1; #pragma omp parallel { #pragma omp single nbthread = omp_get_num_threads(); lock.lock(); for (int i = 0 ; i < REPEAT ; i++) sum ++; lock.unlock(); } EXPECT_EQ(nbthread*REPEAT,sum); }
void TEST_basic_3() { glog_info(MSG("basic_3"), MSG("test lock timeout")); constexpr Interval lock_timeout = 100 * MSEC; Spinlock lock; std::atomic<bool> to_lock{false}; bool locked = false; std::thread th{[&](){ while (!to_lock.load()) { sleep(100 * MSEC); } locked = lock.lock(lock_timeout); }}; // Lock. SpinlockGuard guard(lock); // Run thread. to_lock.store(true); // Wait till thread's lock timed out. th.join(); // Verify. if (locked) { glog_fatal(MSG("err lock timeout")); } }
/******************* FUNCTION *********************/ TEST(TestSpinlock, correctnessOfARIIMode_3) { Spinlock lock; int sum = 0; int nbthread = 1; #pragma omp parallel { #pragma omp single nbthread = omp_get_num_threads(); //already lock to check optional false (if true it will deadlock) lock.lock(); OPTIONAL_CRITICAL(lock,false) for (int i = 0 ; i < REPEAT ; i++) sum ++; END_CRITICAL lock.unlock(); } EXPECT_EQ(nbthread*REPEAT,sum); }
void workOnResource(){ spin.lock(); // shared resource spin.unlock(); }