1 //===-- Linux implementation of the thrd_join function --------------------===// 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 "config/linux/syscall.h" // For syscall function. 10 #include "include/sys/syscall.h" // For syscall numbers. 11 #include "include/threads.h" // For thrd_* type definitions. 12 #include "src/__support/common.h" 13 #include "src/sys/mman/munmap.h" 14 #include "src/threads/linux/thread_utils.h" 15 16 #include <linux/futex.h> // For futex operations. 17 #include <stdatomic.h> // For atomic_load. 18 19 namespace __llvm_libc { 20 LLVM_LIBC_ENTRYPOINT(thrd_join)21int LLVM_LIBC_ENTRYPOINT(thrd_join)(thrd_t *thread, int *retval) { 22 FutexData *clear_tid_address = 23 reinterpret_cast<FutexData *>(thread->__clear_tid); 24 25 // The kernel should set the value at the clear tid address to zero. 26 // If not, it is a spurious wake and we should continue to wait on 27 // the futex. 28 while (atomic_load(clear_tid_address) != 0) { 29 // We cannot do a FUTEX_WAIT_PRIVATE here as the kernel does a 30 // FUTEX_WAKE and not a FUTEX_WAKE_PRIVATE. 31 __llvm_libc::syscall(SYS_futex, clear_tid_address, FUTEX_WAIT, 32 ThreadParams::ClearTIDValue, nullptr); 33 } 34 35 *retval = thread->__retval; 36 37 if (__llvm_libc::munmap(thread->__stack, thread->__stack_size) == -1) 38 return thrd_error; 39 40 return thrd_success; 41 } 42 43 } // namespace __llvm_libc 44