1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2022 Google LLC
2*4bdc9457SAndroid Build Coastguard Worker //
3*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the
4*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree.
5*4bdc9457SAndroid Build Coastguard Worker
6*4bdc9457SAndroid Build Coastguard Worker #include <thread>
7*4bdc9457SAndroid Build Coastguard Worker #include <random>
8*4bdc9457SAndroid Build Coastguard Worker
9*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack.h>
10*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/common.h>
11*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/mutex.h>
12*4bdc9457SAndroid Build Coastguard Worker
13*4bdc9457SAndroid Build Coastguard Worker #include <gtest/gtest.h>
14*4bdc9457SAndroid Build Coastguard Worker
TEST(MUTEX,init_lock_unlock_destroy)15*4bdc9457SAndroid Build Coastguard Worker TEST(MUTEX, init_lock_unlock_destroy) {
16*4bdc9457SAndroid Build Coastguard Worker
17*4bdc9457SAndroid Build Coastguard Worker xnn_mutex m;
18*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(xnn_status_success, xnn_mutex_init(&m));
19*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(xnn_status_success, xnn_mutex_lock(&m));
20*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(xnn_status_success, xnn_mutex_unlock(&m));
21*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(xnn_status_success, xnn_mutex_destroy(&m));
22*4bdc9457SAndroid Build Coastguard Worker }
23*4bdc9457SAndroid Build Coastguard Worker
TEST(MUTEX,counter)24*4bdc9457SAndroid Build Coastguard Worker TEST(MUTEX, counter) {
25*4bdc9457SAndroid Build Coastguard Worker // Skip if we are not targeting pthread.
26*4bdc9457SAndroid Build Coastguard Worker #if XNN_PLATFORM_WEB && !defined(__EMSCRIPTEN_PTHREADS__)
27*4bdc9457SAndroid Build Coastguard Worker GTEST_SKIP();
28*4bdc9457SAndroid Build Coastguard Worker #endif
29*4bdc9457SAndroid Build Coastguard Worker
30*4bdc9457SAndroid Build Coastguard Worker xnn_mutex m;
31*4bdc9457SAndroid Build Coastguard Worker constexpr size_t num_threads = 50;
32*4bdc9457SAndroid Build Coastguard Worker std::vector<std::thread> threads;
33*4bdc9457SAndroid Build Coastguard Worker threads.reserve(num_threads);
34*4bdc9457SAndroid Build Coastguard Worker volatile size_t counter = 0;
35*4bdc9457SAndroid Build Coastguard Worker
36*4bdc9457SAndroid Build Coastguard Worker std::random_device random_device;
37*4bdc9457SAndroid Build Coastguard Worker auto rng = std::mt19937(random_device());
38*4bdc9457SAndroid Build Coastguard Worker auto dist = std::uniform_int_distribution<int>(100, 200);
39*4bdc9457SAndroid Build Coastguard Worker
40*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(xnn_status_success, xnn_mutex_init(&m));
41*4bdc9457SAndroid Build Coastguard Worker
42*4bdc9457SAndroid Build Coastguard Worker for (size_t i = 0; i < num_threads; i++) {
43*4bdc9457SAndroid Build Coastguard Worker threads.emplace_back(([&] () {
44*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(xnn_status_success, xnn_mutex_lock(&m));
45*4bdc9457SAndroid Build Coastguard Worker std::this_thread::sleep_for(std::chrono::milliseconds(dist(rng)));
46*4bdc9457SAndroid Build Coastguard Worker counter += 1;
47*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(xnn_status_success, xnn_mutex_unlock(&m));
48*4bdc9457SAndroid Build Coastguard Worker }));
49*4bdc9457SAndroid Build Coastguard Worker }
50*4bdc9457SAndroid Build Coastguard Worker
51*4bdc9457SAndroid Build Coastguard Worker for (int i = num_threads - 1; i >= 0; i--) {
52*4bdc9457SAndroid Build Coastguard Worker threads[i].join();
53*4bdc9457SAndroid Build Coastguard Worker }
54*4bdc9457SAndroid Build Coastguard Worker
55*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(counter, num_threads);
56*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(xnn_status_success, xnn_mutex_destroy(&m));
57*4bdc9457SAndroid Build Coastguard Worker }
58