1*0a537a12SSiva Chandra Reddy //===-- Tests for pthread_t -----------------------------------------------===//
2*0a537a12SSiva Chandra Reddy //
3*0a537a12SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0a537a12SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5*0a537a12SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0a537a12SSiva Chandra Reddy //
7*0a537a12SSiva Chandra Reddy //===----------------------------------------------------------------------===//
8*0a537a12SSiva Chandra Reddy 
9*0a537a12SSiva Chandra Reddy #include "src/pthread/pthread_create.h"
10*0a537a12SSiva Chandra Reddy #include "src/pthread/pthread_join.h"
11*0a537a12SSiva Chandra Reddy #include "utils/IntegrationTest/test.h"
12*0a537a12SSiva Chandra Reddy 
13*0a537a12SSiva Chandra Reddy #include <pthread.h>
14*0a537a12SSiva Chandra Reddy 
15*0a537a12SSiva Chandra Reddy static constexpr int thread_count = 1000;
16*0a537a12SSiva Chandra Reddy static int counter = 0;
thread_func(void *)17*0a537a12SSiva Chandra Reddy static void *thread_func(void *) {
18*0a537a12SSiva Chandra Reddy   ++counter;
19*0a537a12SSiva Chandra Reddy   return nullptr;
20*0a537a12SSiva Chandra Reddy }
21*0a537a12SSiva Chandra Reddy 
create_and_join()22*0a537a12SSiva Chandra Reddy void create_and_join() {
23*0a537a12SSiva Chandra Reddy   for (counter = 0; counter <= thread_count;) {
24*0a537a12SSiva Chandra Reddy     pthread_t thread;
25*0a537a12SSiva Chandra Reddy     int old_counter_val = counter;
26*0a537a12SSiva Chandra Reddy     ASSERT_EQ(
27*0a537a12SSiva Chandra Reddy         __llvm_libc::pthread_create(&thread, nullptr, thread_func, nullptr), 0);
28*0a537a12SSiva Chandra Reddy 
29*0a537a12SSiva Chandra Reddy     // Start with a retval we dont expect.
30*0a537a12SSiva Chandra Reddy     void *retval = reinterpret_cast<void *>(thread_count + 1);
31*0a537a12SSiva Chandra Reddy     ASSERT_EQ(__llvm_libc::pthread_join(thread, &retval), 0);
32*0a537a12SSiva Chandra Reddy     ASSERT_EQ(uintptr_t(retval), uintptr_t(nullptr));
33*0a537a12SSiva Chandra Reddy     ASSERT_EQ(counter, old_counter_val + 1);
34*0a537a12SSiva Chandra Reddy   }
35*0a537a12SSiva Chandra Reddy }
36*0a537a12SSiva Chandra Reddy 
return_arg(void * arg)37*0a537a12SSiva Chandra Reddy static void *return_arg(void *arg) { return arg; }
38*0a537a12SSiva Chandra Reddy 
spawn_and_join()39*0a537a12SSiva Chandra Reddy void spawn_and_join() {
40*0a537a12SSiva Chandra Reddy   pthread_t thread_list[thread_count];
41*0a537a12SSiva Chandra Reddy   int args[thread_count];
42*0a537a12SSiva Chandra Reddy 
43*0a537a12SSiva Chandra Reddy   for (int i = 0; i < thread_count; ++i) {
44*0a537a12SSiva Chandra Reddy     args[i] = i;
45*0a537a12SSiva Chandra Reddy     ASSERT_EQ(__llvm_libc::pthread_create(thread_list + i, nullptr, return_arg,
46*0a537a12SSiva Chandra Reddy                                           args + i),
47*0a537a12SSiva Chandra Reddy               0);
48*0a537a12SSiva Chandra Reddy   }
49*0a537a12SSiva Chandra Reddy 
50*0a537a12SSiva Chandra Reddy   for (int i = 0; i < thread_count; ++i) {
51*0a537a12SSiva Chandra Reddy     // Start with a retval we dont expect.
52*0a537a12SSiva Chandra Reddy     void *retval = reinterpret_cast<void *>(thread_count + 1);
53*0a537a12SSiva Chandra Reddy     ASSERT_EQ(__llvm_libc::pthread_join(thread_list[i], &retval), 0);
54*0a537a12SSiva Chandra Reddy     ASSERT_EQ(*reinterpret_cast<int *>(retval), i);
55*0a537a12SSiva Chandra Reddy   }
56*0a537a12SSiva Chandra Reddy }
57*0a537a12SSiva Chandra Reddy 
main()58*0a537a12SSiva Chandra Reddy int main() {
59*0a537a12SSiva Chandra Reddy   create_and_join();
60*0a537a12SSiva Chandra Reddy   spawn_and_join();
61*0a537a12SSiva Chandra Reddy   return 0;
62*0a537a12SSiva Chandra Reddy }
63