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