diff --git a/starboard/nplb/atomic_base_test.cc b/starboard/nplb/atomic_base_test.cc index db0399788d5a..f49990ee943f 100644 --- a/starboard/nplb/atomic_base_test.cc +++ b/starboard/nplb/atomic_base_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -33,30 +34,24 @@ namespace { // thread. Subclasses must override Run(). class TestThread { public: - TestThread() : thread_(kSbThreadInvalid) {} + TestThread() : thread_(0) {} virtual ~TestThread() {} // Subclasses should override the Run method. virtual void Run() = 0; - // Calls SbThreadCreate() with default parameters. + // Calls pthread_create() with default parameters. void Start() { - SbThreadEntryPoint entry_point = ThreadEntryPoint; + pthread_create(&thread_, nullptr, ThreadEntryPoint, this); - thread_ = SbThreadCreate(0, // default stack_size. - kSbThreadNoPriority, // default priority. - kSbThreadNoAffinity, // default affinity. - true, // joinable. - "TestThread", entry_point, this); - - if (kSbThreadInvalid == thread_) { + if (thread_ == 0) { ADD_FAILURE_AT(__FILE__, __LINE__) << "Invalid thread."; } return; } void Join() { - if (!SbThreadJoin(thread_, NULL)) { + if (pthread_join(thread_, NULL) != 0) { ADD_FAILURE_AT(__FILE__, __LINE__) << "Could not join thread."; } } @@ -68,7 +63,7 @@ class TestThread { return NULL; } - SbThread thread_; + pthread_t thread_; TestThread(const TestThread&) = delete; void operator=(const TestThread&) = delete; diff --git a/starboard/nplb/atomic_test.cc b/starboard/nplb/atomic_test.cc index 64a3e095e0a7..44dfd1500875 100644 --- a/starboard/nplb/atomic_test.cc +++ b/starboard/nplb/atomic_test.cc @@ -340,6 +340,7 @@ struct TestOnceContext { // The entry point for all the threads spawned during TestOnce(). template void* TestOnceEntryPoint(void* raw_context) { + pthread_setname_np(pthread_self(), "TestOnceThread"); // Force every thread to sleep immediately so the first thread doesn't always // just win. usleep(1000); @@ -376,21 +377,20 @@ TYPED_TEST(AdvancedSbAtomicTest, OnceMultipleThreads) { // Start up kNumThreads to fight over initializing |target_data|. TestOnceContext contexts[kNumThreads] = {0}; - SbThread threads[kNumThreads] = {0}; + pthread_t threads[kNumThreads] = {0}; for (int i = 0; i < kNumThreads; ++i) { contexts[i].data = data + i * kDataPerThread; contexts[i].out_data = target_data; contexts[i].state = &state; contexts[i].size = kDataPerThread; - threads[i] = SbThreadCreate( - 0, kSbThreadNoPriority, kSbThreadNoAffinity, true, "TestOnceThread", - TestOnceEntryPoint, &(contexts[i])); - EXPECT_TRUE(SbThreadIsValid(threads[i])); + pthread_create(&threads[i], nullptr, TestOnceEntryPoint, + &(contexts[i])); + EXPECT_TRUE(threads[i] != 0); } // Wait for all threads to complete, and clean up their resources. for (int i = 0; i < kNumThreads; ++i) { - EXPECT_TRUE(SbThreadJoin(threads[i], NULL)); + EXPECT_EQ(pthread_join(threads[i], NULL), 0); } // Ensure that exactly one thread initialized the data. @@ -412,6 +412,7 @@ const int kNumIncrements = 4000; template void* IncrementEntryPoint(void* raw_context) { + pthread_setname_np(pthread_self(), "TestIncrementThread"); SbAtomicType* target = reinterpret_cast(raw_context); for (int i = 0; i < kNumIncrements; ++i) { atomic::NoBarrier_Increment(target, 1); @@ -421,6 +422,7 @@ void* IncrementEntryPoint(void* raw_context) { template void* DecrementEntryPoint(void* raw_context) { + pthread_setname_np(pthread_self(), "TestDecrementThread"); SbAtomicType* target = reinterpret_cast(raw_context); for (int i = 0; i < kNumIncrements; ++i) { atomic::NoBarrier_Increment(target, -1); @@ -439,27 +441,25 @@ TYPED_TEST(AdvancedSbAtomicTest, IncrementDecrementMultipleThreads) { TypeParam value = kTestValue; // Start up kNumThreads to fight. - SbThread threads[kNumThreads] = {0}; + pthread_t threads[kNumThreads] = {0}; // First half are incrementers. for (int i = 0; i < kNumThreads / 2; ++i) { - threads[i] = SbThreadCreate(0, kSbThreadNoPriority, kSbThreadNoAffinity, - true, "TestIncrementThread", - IncrementEntryPoint, &value); - EXPECT_TRUE(SbThreadIsValid(threads[i])); + pthread_create(&threads[i], nullptr, IncrementEntryPoint, + &value); + EXPECT_TRUE(threads[i] != 0); } // Second half are decrementers. for (int i = kNumThreads / 2; i < kNumThreads; ++i) { - threads[i] = SbThreadCreate(0, kSbThreadNoPriority, kSbThreadNoAffinity, - true, "TestDecrementThread", - DecrementEntryPoint, &value); - EXPECT_TRUE(SbThreadIsValid(threads[i])); + pthread_create(&threads[i], nullptr, DecrementEntryPoint, + &value); + EXPECT_TRUE(threads[i] != 0); } // Wait for all threads to complete, and clean up their resources. for (int i = 0; i < kNumThreads; ++i) { - EXPECT_TRUE(SbThreadJoin(threads[i], NULL)); + EXPECT_EQ(pthread_join(threads[i], NULL), 0); } // |value| should be back to its original value. If the increment/decrement diff --git a/starboard/nplb/multiple_player_test.cc b/starboard/nplb/multiple_player_test.cc index 5b64149c8495..2ddbb11082cc 100644 --- a/starboard/nplb/multiple_player_test.cc +++ b/starboard/nplb/multiple_player_test.cc @@ -19,7 +19,7 @@ #include "starboard/nplb/maximum_player_configuration_explorer.h" #include "starboard/nplb/player_test_fixture.h" #include "starboard/nplb/player_test_util.h" -#include "starboard/nplb/thread_helpers.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "starboard/testing/fake_graphics_context_provider.h" #include "testing/gtest/include/gtest/gtest.h" @@ -36,7 +36,7 @@ typedef std::function MultiplePlayerTestFunctor; -class PlayerThread : public AbstractTestThread { +class PlayerThread : public posix::AbstractTestThread { public: explicit PlayerThread(const std::function& functor) : functor_(functor) {} diff --git a/starboard/nplb/player_write_sample_test.cc b/starboard/nplb/player_write_sample_test.cc index f9ac21a8d9b0..a954ee69f1d1 100644 --- a/starboard/nplb/player_write_sample_test.cc +++ b/starboard/nplb/player_write_sample_test.cc @@ -17,7 +17,7 @@ #include "starboard/nplb/player_creation_param_helpers.h" #include "starboard/nplb/player_test_fixture.h" #include "starboard/nplb/player_test_util.h" -#include "starboard/nplb/thread_helpers.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "starboard/string.h" #include "starboard/testing/fake_graphics_context_provider.h" #include "testing/gtest/include/gtest/gtest.h" @@ -329,7 +329,7 @@ TEST_P(SbPlayerWriteSampleTest, DiscardAllAudio) { << "."; } -class SecondaryPlayerTestThread : public AbstractTestThread { +class SecondaryPlayerTestThread : public posix::AbstractTestThread { public: SecondaryPlayerTestThread( const SbPlayerTestConfig& config, diff --git a/starboard/nplb/posix_compliance/posix_mutex_acquire_try_test.cc b/starboard/nplb/posix_compliance/posix_mutex_acquire_try_test.cc index 40a9458aeff3..2c2d6c0c158c 100644 --- a/starboard/nplb/posix_compliance/posix_mutex_acquire_try_test.cc +++ b/starboard/nplb/posix_compliance/posix_mutex_acquire_try_test.cc @@ -17,7 +17,7 @@ #include "starboard/configuration.h" #include "testing/gtest/include/gtest/gtest.h" -#include "starboard/nplb/thread_helpers.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "starboard/thread.h" namespace starboard { @@ -32,7 +32,7 @@ struct TestContext { }; void* EntryPoint(void* parameter) { - pthread_setname_np(pthread_self(), nplb::kThreadName); + pthread_setname_np(pthread_self(), posix::kThreadName); TestContext* context = static_cast(parameter); context->was_locked_ = (pthread_mutex_trylock(context->mutex_) == 0); return NULL; diff --git a/starboard/nplb/posix_compliance/posix_thread_get_name_test.cc b/starboard/nplb/posix_compliance/posix_thread_get_name_test.cc index 5093ca4fb5f0..d9a8a62e9354 100644 --- a/starboard/nplb/posix_compliance/posix_thread_get_name_test.cc +++ b/starboard/nplb/posix_compliance/posix_thread_get_name_test.cc @@ -14,7 +14,7 @@ #include -#include "starboard/nplb/thread_helpers.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace starboard { @@ -22,7 +22,7 @@ namespace nplb { namespace { void* GetThreadNameEntryPoint(void* context) { - pthread_setname_np(pthread_self(), kThreadName); + pthread_setname_np(pthread_self(), posix::kThreadName); char name[4096] = {0}; pthread_getname_np(pthread_self(), name, SB_ARRAY_SIZE_INT(name)); @@ -39,7 +39,7 @@ TEST(PosixThreadGetNameTest, SunnyDay) { EXPECT_TRUE(thread != 0); EXPECT_EQ(pthread_join(thread, NULL), 0); - EXPECT_EQ(kThreadName, result); + EXPECT_EQ(posix::kThreadName, result); } } // namespace diff --git a/starboard/nplb/posix_compliance/posix_thread_set_name_test.cc b/starboard/nplb/posix_compliance/posix_thread_set_name_test.cc index 6019a4da78b7..e1182da30e2f 100644 --- a/starboard/nplb/posix_compliance/posix_thread_set_name_test.cc +++ b/starboard/nplb/posix_compliance/posix_thread_set_name_test.cc @@ -14,7 +14,7 @@ #include -#include "starboard/nplb/thread_helpers.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace starboard { @@ -45,14 +45,14 @@ void* SetThreadNameEntryPoint(void* context) { TEST(PosixThreadSetNameTest, SunnyDay) { Context context; - context.name_to_set = kAltThreadName; + context.name_to_set = posix::kAltThreadName; pthread_t thread; EXPECT_EQ(pthread_create(&thread, NULL, SetThreadNameEntryPoint, &context), 0); EXPECT_TRUE(thread != 0); EXPECT_EQ(pthread_join(thread, NULL), 0); - EXPECT_NE(kAltThreadName, context.got_name1); - EXPECT_EQ(kAltThreadName, context.got_name2); + EXPECT_NE(posix::kAltThreadName, context.got_name1); + EXPECT_EQ(posix::kAltThreadName, context.got_name2); } } // namespace diff --git a/starboard/nplb/recursive_mutex_test.cc b/starboard/nplb/recursive_mutex_test.cc index bed9170f66b0..7841065cd09b 100644 --- a/starboard/nplb/recursive_mutex_test.cc +++ b/starboard/nplb/recursive_mutex_test.cc @@ -13,7 +13,8 @@ // limitations under the License. #include "starboard/common/recursive_mutex.h" -#include "starboard/nplb/thread_helpers.h" +#include "starboard/common/condition_variable.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace starboard { @@ -79,7 +80,7 @@ TEST(RecursiveMutex, TryLocksInRecursion) { EXPECT_TRUE(rmutex.AcquireTry()); } -class ThreadBlockedRecursiveMutex : public AbstractTestThread { +class ThreadBlockedRecursiveMutex : public posix::AbstractTestThread { public: explicit ThreadBlockedRecursiveMutex(RecursiveMutex* s) : rmutex_(s) {} void Run() override { EXPECT_FALSE(rmutex_->AcquireTry()); } @@ -98,7 +99,7 @@ TEST(RecursiveMutex, BlockOtherThread) { EXPECT_TRUE(rmutex.AcquireTry()); } -class ThreadAcquiresRecursiveMutex : public AbstractTestThread { +class ThreadAcquiresRecursiveMutex : public posix::AbstractTestThread { public: explicit ThreadAcquiresRecursiveMutex(RecursiveMutex* s, Mutex* cv_mutex, diff --git a/starboard/nplb/rwlock_test.cc b/starboard/nplb/rwlock_test.cc index a7714f1ada24..2cb52a5115f7 100644 --- a/starboard/nplb/rwlock_test.cc +++ b/starboard/nplb/rwlock_test.cc @@ -15,10 +15,10 @@ #include #include "starboard/common/rwlock.h" +#include "starboard/common/semaphore.h" #include "starboard/common/time.h" #include "starboard/configuration.h" -#include "starboard/nplb/thread_helpers.h" -#include "starboard/thread.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "testing/gtest/include/gtest/gtest.h" // Increasing threads by 2x increases testing time by 3x, due to write @@ -43,7 +43,7 @@ TEST(RWLock, Use) { } // Enters a RWLock as a reader and then increments a counter indicating that it -class ReadAndSignalTestThread : public AbstractTestThread { +class ReadAndSignalTestThread : public posix::AbstractTestThread { public: struct SharedData { SharedData() @@ -100,7 +100,7 @@ TEST(RWLock, ReadAcquisitionTwoThreads) { // Tests the expectation that a read lock will be blocked for X milliseconds // while the thread is holding the write lock. -class ThreadHoldsWriteLockForTime : public AbstractTestThread { +class ThreadHoldsWriteLockForTime : public posix::AbstractTestThread { public: struct SharedData { explicit SharedData(int64_t time_hold) : time_to_hold(time_hold) {} @@ -144,7 +144,7 @@ TEST(RWLock, FLAKY_HoldsLockForTime) { // This thread tests RWLock by generating numbers and writing to a // shared set. Additionally readbacks are interleaved in writes. -class ThreadRWLockStressTest : public AbstractTestThread { +class ThreadRWLockStressTest : public posix::AbstractTestThread { public: struct SharedData { RWLock rw_lock; @@ -159,8 +159,6 @@ class ThreadRWLockStressTest : public AbstractTestThread { shared_data_(shared_data) {} void Run() override { - SbThread current_thread = SbThreadGetCurrent(); - for (int32_t i = begin_value_; i < end_value_; ++i) { DoReadAll(); DoWrite(i); @@ -199,7 +197,7 @@ TEST(RWLock, RWLockStressTest) { kNumValuesEachThread * NUM_STRESS_THREADS; ThreadRWLockStressTest::SharedData shared_data; - std::vector threads; + std::vector threads; for (int i = 0; i < NUM_STRESS_THREADS; ++i) { int32_t start_value = i * kNumValuesEachThread; diff --git a/starboard/nplb/semaphore_test.cc b/starboard/nplb/semaphore_test.cc index 97379b4a82c6..ecb40d495c4e 100644 --- a/starboard/nplb/semaphore_test.cc +++ b/starboard/nplb/semaphore_test.cc @@ -16,7 +16,7 @@ #include "starboard/common/semaphore.h" #include "starboard/common/time.h" -#include "starboard/nplb/thread_helpers.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace starboard { @@ -49,7 +49,7 @@ TEST(Semaphore, InitialValue_One) { EXPECT_FALSE(semaphore.TakeTry()); } -class ThreadTakesSemaphore : public AbstractTestThread { +class ThreadTakesSemaphore : public posix::AbstractTestThread { public: explicit ThreadTakesSemaphore(Semaphore* s) : semaphore_(s) {} void Run() override { semaphore_->Take(); } @@ -65,7 +65,7 @@ TEST(Semaphore, ThreadTakes) { thread.Join(); } -class ThreadTakesWaitSemaphore : public AbstractTestThread { +class ThreadTakesWaitSemaphore : public posix::AbstractTestThread { public: explicit ThreadTakesWaitSemaphore(int64_t wait_us) : thread_started_(false), @@ -153,7 +153,7 @@ TEST(Semaphore, ThreadTakesWait_TimeExpires) { EXPECT_TRUE(false) << "Thread waited, but time exceeded expectations."; } -class ThreadPutsSemaphore : public AbstractTestThread { +class ThreadPutsSemaphore : public posix::AbstractTestThread { public: explicit ThreadPutsSemaphore(Semaphore* s) : semaphore_(s) {} void Run() override { semaphore_->Put(); } diff --git a/starboard/nplb/socket_send_to_test.cc b/starboard/nplb/socket_send_to_test.cc index ba34fbc21cbb..0f42f9b1e4d2 100644 --- a/starboard/nplb/socket_send_to_test.cc +++ b/starboard/nplb/socket_send_to_test.cc @@ -15,6 +15,7 @@ // SendTo is largely tested with ReceiveFrom, so look there for more involved // tests. +#include #include #include @@ -41,6 +42,7 @@ class PairSbSocketSendToTest // Thread entry point to continuously write to a socket that is expected to // be closed on another thread. void* SendToServerSocketEntryPoint(void* trio_as_void_ptr) { + pthread_setname_np(pthread_self(), "SendToTest"); ConnectedTrio* trio = static_cast(trio_as_void_ptr); // The contents of this buffer are inconsequential. const size_t kBufSize = 1024; @@ -97,17 +99,16 @@ TEST_P(PairSbSocketSendToTest, RainyDaySendToClosedSocket) { EXPECT_TRUE(SbSocketDestroy(trio.listen_socket)); // Start a thread to write to the client socket. - const bool kJoinable = true; - SbThread send_thread = SbThreadCreate( - 0, kSbThreadNoPriority, kSbThreadNoAffinity, kJoinable, "SendToTest", - SendToServerSocketEntryPoint, static_cast(&trio)); + pthread_t send_thread = 0; + pthread_create(&send_thread, nullptr, SendToServerSocketEntryPoint, + static_cast(&trio)); // Close the client, which should cause writes to the server socket to fail. EXPECT_TRUE(SbSocketDestroy(trio.client_socket)); // Wait for the thread to exit and check the last socket error. void* thread_result; - EXPECT_TRUE(SbThreadJoin(send_thread, &thread_result)); + EXPECT_EQ(pthread_join(send_thread, &thread_result), 0); EXPECT_SB_SOCKET_ERROR_IN(SbSocketGetLastError(trio.server_socket), kSbSocketErrorConnectionReset, diff --git a/starboard/nplb/socket_waiter_wait_test.cc b/starboard/nplb/socket_waiter_wait_test.cc index 373880879305..487ff085d4c0 100644 --- a/starboard/nplb/socket_waiter_wait_test.cc +++ b/starboard/nplb/socket_waiter_wait_test.cc @@ -15,11 +15,11 @@ #include #include "starboard/common/log.h" +#include "starboard/common/semaphore.h" #include "starboard/common/socket.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "starboard/nplb/socket_helpers.h" -#include "starboard/nplb/thread_helpers.h" #include "starboard/socket_waiter.h" -#include "starboard/thread.h" #include "testing/gtest/include/gtest/gtest.h" namespace starboard { @@ -240,15 +240,14 @@ TEST_P(PairSbSocketWaiterWaitTest, SunnyDayAlreadyReady) { &context, &AlreadyReadySocketWaiterCallback, kSbSocketWaiterInterestRead, false)); - SbThread thread = - SbThreadCreate(0, kSbThreadNoPriority, kSbThreadNoAffinity, true, NULL, - AlreadyReadyEntryPoint, &context); - EXPECT_TRUE(SbThreadIsValid(thread)); + pthread_t thread = 0; + pthread_create(&thread, nullptr, AlreadyReadyEntryPoint, &context); + EXPECT_TRUE(thread != 0); context.wrote_a_signal.Take(); WaitShouldNotBlock(context.waiter); - EXPECT_TRUE(SbThreadJoin(thread, NULL)); + EXPECT_EQ(pthread_join(thread, NULL), 0); } TEST_F(SbSocketWaiterWaitTest, RainyDayInvalidWaiter) { diff --git a/starboard/nplb/socket_waiter_wake_up_test.cc b/starboard/nplb/socket_waiter_wake_up_test.cc index 520429c10da4..1e3896d56019 100644 --- a/starboard/nplb/socket_waiter_wake_up_test.cc +++ b/starboard/nplb/socket_waiter_wake_up_test.cc @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include "starboard/common/semaphore.h" #include "starboard/common/time.h" +#include "starboard/nplb/posix_compliance/posix_thread_helpers.h" #include "starboard/nplb/socket_helpers.h" -#include "starboard/nplb/thread_helpers.h" #include "starboard/socket_waiter.h" -#include "starboard/thread.h" #include "testing/gtest/include/gtest/gtest.h" namespace starboard { @@ -33,6 +34,8 @@ struct WakeUpContext { Semaphore semaphore; }; +typedef void* (*ThreadEntryPoint)(void*); + void* WakeUpEntryPoint(void* context) { SbSocketWaiter waiter = reinterpret_cast(context); SbSocketWaiterWakeUp(waiter); @@ -48,19 +51,18 @@ void* WakeUpSleepEntryPoint(void* context) { return NULL; } -SbThread Spawn(void* context, SbThreadEntryPoint entry) { - SbThread thread = - SbThreadCreate(0, kSbThreadPriorityNormal, kSbThreadNoAffinity, true, - NULL, entry, context); - EXPECT_TRUE(SbThreadIsValid(thread)); +pthread_t Spawn(void* context, ThreadEntryPoint entry) { + pthread_t thread = 0; + pthread_create(&thread, nullptr, entry, context); + EXPECT_TRUE(thread != 0); return thread; } -void Join(SbThread thread) { - EXPECT_TRUE(SbThreadJoin(thread, NULL)); +void Join(pthread_t thread) { + EXPECT_EQ(pthread_join(thread, NULL), 0); } -void SpawnJoin(void* context, SbThreadEntryPoint entry) { +void SpawnJoin(void* context, ThreadEntryPoint entry) { Join(Spawn(context, entry)); } @@ -127,7 +129,7 @@ TEST(SbSocketWaiterWakeUpTest, CallFromOtherThreadWakesUp) { WakeUpContext context; context.waiter = waiter; - SbThread thread = Spawn(&context, &WakeUpSleepEntryPoint); + pthread_t thread = Spawn(&context, &WakeUpSleepEntryPoint); int64_t start = CurrentMonotonicTime(); context.semaphore.Put(); TimedWait(waiter); diff --git a/starboard/nplb/system_hide_splash_screen_test.cc b/starboard/nplb/system_hide_splash_screen_test.cc index 9d2e8e383ecd..6bcf6ef420e2 100644 --- a/starboard/nplb/system_hide_splash_screen_test.cc +++ b/starboard/nplb/system_hide_splash_screen_test.cc @@ -15,8 +15,9 @@ // Here we are not trying to do anything fancy, just to really sanity check that // this is hooked up to something. +#include + #include "starboard/system.h" -#include "starboard/thread.h" #include "testing/gtest/include/gtest/gtest.h" namespace starboard { @@ -24,6 +25,7 @@ namespace nplb { namespace { void* ThreadFunc(void* context) { + pthread_setname_np(pthread_self(), "HideSplashTest"); SbSystemHideSplashScreen(); return NULL; } @@ -38,12 +40,10 @@ TEST(SbSystemHideSplashScreenTest, SunnyDay) { TEST(SbSystemHideSplashScreenTest, SunnyDayNewThread) { // We should be able to call the function from any thread. - const char kThreadName[] = "HideSplashTest"; - SbThread thread = SbThreadCreate(0 /*stack_size*/, kSbThreadPriorityNormal, - kSbThreadNoAffinity, true /*joinable*/, - kThreadName, ThreadFunc, NULL /*context*/); - EXPECT_TRUE(SbThreadIsValid(thread)); - SbThreadJoin(thread, NULL /*out_return*/); + pthread_t thread = 0; + pthread_create(&thread, nullptr, ThreadFunc, nullptr); + EXPECT_TRUE(thread != 0); + pthread_join(thread, NULL /*out_return*/); } } // namespace