xref: /aosp_15_r20/external/llvm-libc/test/integration/src/threads/tss_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Tests for TSS API like tss_set, tss_get etc. ----------------------===//
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/threads/thrd_create.h"
10 #include "src/threads/thrd_exit.h"
11 #include "src/threads/thrd_join.h"
12 #include "src/threads/tss_create.h"
13 #include "src/threads/tss_delete.h"
14 #include "src/threads/tss_get.h"
15 #include "src/threads/tss_set.h"
16 #include "test/IntegrationTest/test.h"
17 
18 #include <threads.h>
19 
20 static constexpr int THREAD_DATA_INITVAL = 0x1234;
21 static constexpr int THREAD_DATA_FINIVAL = 0x4321;
22 static constexpr int THREAD_RUN_VAL = 0x600D;
23 
24 int child_thread_data = THREAD_DATA_INITVAL;
25 int main_thread_data = THREAD_DATA_INITVAL;
26 
27 tss_t key;
dtor(void * data)28 void dtor(void *data) {
29   auto *v = reinterpret_cast<int *>(data);
30   *v = THREAD_DATA_FINIVAL;
31 }
32 
func(void * obj)33 int func(void *obj) {
34   ASSERT_EQ(LIBC_NAMESPACE::tss_set(key, &child_thread_data), thrd_success);
35   int *d = reinterpret_cast<int *>(LIBC_NAMESPACE::tss_get(key));
36   ASSERT_TRUE(d != nullptr);
37   ASSERT_EQ(&child_thread_data, d);
38   ASSERT_EQ(*d, THREAD_DATA_INITVAL);
39   *reinterpret_cast<int *>(obj) = THREAD_RUN_VAL;
40   return 0;
41 }
42 
TEST_MAIN()43 TEST_MAIN() {
44   ASSERT_EQ(LIBC_NAMESPACE::tss_create(&key, &dtor), thrd_success);
45   ASSERT_EQ(LIBC_NAMESPACE::tss_set(key, &main_thread_data), thrd_success);
46   int *d = reinterpret_cast<int *>(LIBC_NAMESPACE::tss_get(key));
47   ASSERT_TRUE(d != nullptr);
48   ASSERT_EQ(&main_thread_data, d);
49   ASSERT_EQ(*d, THREAD_DATA_INITVAL);
50 
51   thrd_t th;
52   int arg = 0xBAD;
53   ASSERT_EQ(LIBC_NAMESPACE::thrd_create(&th, &func, &arg), thrd_success);
54   int retval = THREAD_DATA_INITVAL; // Init to some non-zero val.
55   ASSERT_EQ(LIBC_NAMESPACE::thrd_join(th, &retval), thrd_success);
56   ASSERT_EQ(retval, 0);
57   ASSERT_EQ(arg, THREAD_RUN_VAL);
58   ASSERT_EQ(child_thread_data, THREAD_DATA_FINIVAL);
59 
60   LIBC_NAMESPACE::tss_delete(key);
61 
62   return 0;
63 }
64