1*4e366538SXin Li /*
2*4e366538SXin Li * Copyright 2017 The LibYuv Project Authors. All rights reserved.
3*4e366538SXin Li *
4*4e366538SXin Li * Use of this source code is governed by a BSD-style license
5*4e366538SXin Li * that can be found in the LICENSE file in the root of the source
6*4e366538SXin Li * tree. An additional intellectual property rights grant can be found
7*4e366538SXin Li * in the file PATENTS. All contributing project authors may
8*4e366538SXin Li * be found in the AUTHORS file in the root of the source tree.
9*4e366538SXin Li */
10*4e366538SXin Li
11*4e366538SXin Li #include <gtest/gtest.h>
12*4e366538SXin Li
13*4e366538SXin Li #include "libyuv/cpu_id.h"
14*4e366538SXin Li
15*4e366538SXin Li #if defined(__clang__) && !defined(__wasm__)
16*4e366538SXin Li #if __has_include(<pthread.h>)
17*4e366538SXin Li #define LIBYUV_HAVE_PTHREAD 1
18*4e366538SXin Li #endif
19*4e366538SXin Li #elif defined(__linux__)
20*4e366538SXin Li #define LIBYUV_HAVE_PTHREAD 1
21*4e366538SXin Li #endif
22*4e366538SXin Li
23*4e366538SXin Li #ifdef LIBYUV_HAVE_PTHREAD
24*4e366538SXin Li #include <pthread.h>
25*4e366538SXin Li #endif
26*4e366538SXin Li
27*4e366538SXin Li namespace libyuv {
28*4e366538SXin Li
29*4e366538SXin Li #ifdef LIBYUV_HAVE_PTHREAD
ThreadMain(void * arg)30*4e366538SXin Li void* ThreadMain(void* arg) {
31*4e366538SXin Li int* flags = static_cast<int*>(arg);
32*4e366538SXin Li
33*4e366538SXin Li *flags = TestCpuFlag(kCpuInitialized);
34*4e366538SXin Li return nullptr;
35*4e366538SXin Li }
36*4e366538SXin Li #endif // LIBYUV_HAVE_PTHREAD
37*4e366538SXin Li
38*4e366538SXin Li // Call TestCpuFlag() from two threads. ThreadSanitizer should not report any
39*4e366538SXin Li // data race.
TEST(LibYUVCpuThreadTest,TestCpuFlagMultipleThreads)40*4e366538SXin Li TEST(LibYUVCpuThreadTest, TestCpuFlagMultipleThreads) {
41*4e366538SXin Li #ifdef LIBYUV_HAVE_PTHREAD
42*4e366538SXin Li int cpu_flags1;
43*4e366538SXin Li int cpu_flags2;
44*4e366538SXin Li int ret;
45*4e366538SXin Li pthread_t thread1;
46*4e366538SXin Li pthread_t thread2;
47*4e366538SXin Li
48*4e366538SXin Li MaskCpuFlags(0); // Reset to 0 to allow auto detect.
49*4e366538SXin Li ret = pthread_create(&thread1, nullptr, ThreadMain, &cpu_flags1);
50*4e366538SXin Li ASSERT_EQ(ret, 0);
51*4e366538SXin Li ret = pthread_create(&thread2, nullptr, ThreadMain, &cpu_flags2);
52*4e366538SXin Li ASSERT_EQ(ret, 0);
53*4e366538SXin Li ret = pthread_join(thread1, nullptr);
54*4e366538SXin Li EXPECT_EQ(ret, 0);
55*4e366538SXin Li ret = pthread_join(thread2, nullptr);
56*4e366538SXin Li EXPECT_EQ(ret, 0);
57*4e366538SXin Li EXPECT_EQ(cpu_flags1, cpu_flags2);
58*4e366538SXin Li #else
59*4e366538SXin Li printf("pthread unavailable; Test skipped.");
60*4e366538SXin Li #endif // LIBYUV_HAVE_PTHREAD
61*4e366538SXin Li }
62*4e366538SXin Li
63*4e366538SXin Li } // namespace libyuv
64