1 //===-- Tests for pthread_equal -------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/pthread/pthread_create.h" 10 #include "src/pthread/pthread_equal.h" 11 #include "src/pthread/pthread_join.h" 12 #include "src/pthread/pthread_mutex_destroy.h" 13 #include "src/pthread/pthread_mutex_init.h" 14 #include "src/pthread/pthread_mutex_lock.h" 15 #include "src/pthread/pthread_mutex_unlock.h" 16 #include "src/pthread/pthread_self.h" 17 18 #include "utils/IntegrationTest/test.h" 19 20 #include <pthread.h> 21 22 pthread_t child_thread; 23 pthread_mutex_t mutex; 24 25 static void *child_func(void *arg) { 26 __llvm_libc::pthread_mutex_lock(&mutex); 27 int *ret = reinterpret_cast<int *>(arg); 28 auto self = __llvm_libc::pthread_self(); 29 *ret = __llvm_libc::pthread_equal(child_thread, self); 30 __llvm_libc::pthread_mutex_unlock(&mutex); 31 return nullptr; 32 } 33 34 int main() { 35 // We init and lock the mutex so that we guarantee that the child thread is 36 // waiting after startup. 37 ASSERT_EQ(__llvm_libc::pthread_mutex_init(&mutex, nullptr), 0); 38 ASSERT_EQ(__llvm_libc::pthread_mutex_lock(&mutex), 0); 39 40 auto main_thread = __llvm_libc::pthread_self(); 41 42 // The idea here is that, we start a child thread which will immediately 43 // wait on |mutex|. The main thread will update the global |child_thread| var 44 // and unlock |mutex|. This will give the child thread a chance to compare 45 // the result of pthread_self with the |child_thread|. The result of the 46 // comparison is returned in the thread arg. 47 int result = 0; 48 pthread_t th; 49 ASSERT_EQ(__llvm_libc::pthread_create(&th, nullptr, child_func, &result), 0); 50 // This new thread should of course not be equal to the main thread. 51 ASSERT_EQ(__llvm_libc::pthread_equal(th, main_thread), 0); 52 53 // Set the |child_thread| global var and unlock to allow the child to perform 54 // the comparison. 55 child_thread = th; 56 ASSERT_EQ(__llvm_libc::pthread_mutex_unlock(&mutex), 0); 57 58 void *retval; 59 ASSERT_EQ(__llvm_libc::pthread_join(th, &retval), 0); 60 ASSERT_EQ(uintptr_t(retval), uintptr_t(nullptr)); 61 // The child thread should see that pthread_self return value is the same as 62 // |child_thread|. 63 ASSERT_NE(result, 0); 64 65 __llvm_libc::pthread_mutex_destroy(&mutex); 66 return 0; 67 } 68