| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| //===-- Linux implementation of the pthread_getspecific function ----------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "pthread_getspecific.h" | ||
|
|
||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/thread.h" | ||
|
|
||
| #include <pthread.h> | ||
| #include <stddef.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(void *, pthread_getspecific, (pthread_key_t key)) { | ||
| return get_tss_value(key); | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| //===-- Implementation header for pthread_getspecific function --*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_GETSPECIFIC_H | ||
| #define LLVM_LIBC_SRC_PTHREAD_PTHREAD_GETSPECIFIC_H | ||
|
|
||
| #include <pthread.h> | ||
| #include <stddef.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| void *pthread_getspecific(pthread_key_t); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_GETSPECIFIC_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //===-- Implementation of the pthread_key_create --------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "pthread_key_create.h" | ||
|
|
||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/thread.h" | ||
|
|
||
| #include <errno.h> | ||
| #include <pthread.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, pthread_key_create, | ||
| (pthread_key_t * key, __pthread_tss_dtor_t dtor)) { | ||
| auto k = __llvm_libc::new_tss_key(dtor); | ||
| if (!k) | ||
| return EINVAL; | ||
| *key = *k; | ||
| return 0; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for pthread_key_create ------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_KEY_CREATE_H | ||
| #define LLVM_LIBC_SRC_PTHREAD_PTHREAD_KEY_CREATE_H | ||
|
|
||
| #include <pthread.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int pthread_key_create(pthread_key_t *key, __pthread_tss_dtor_t dtor); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_KEY_CREATE_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| //===-- Implementation of the pthread_key_delete --------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "pthread_key_delete.h" | ||
|
|
||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/thread.h" | ||
|
|
||
| #include <errno.h> | ||
| #include <pthread.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, pthread_key_delete, (pthread_key_t key)) { | ||
| if (__llvm_libc::tss_key_delete(key)) | ||
| return 0; | ||
| else | ||
| return EINVAL; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for pthread_key_delete ------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_KEY_DELETE_H | ||
| #define LLVM_LIBC_SRC_PTHREAD_PTHREAD_KEY_DELETE_H | ||
|
|
||
| #include <pthread.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int pthread_key_delete(pthread_key_t key); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_KEY_DELETE_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| //===-- Linux implementation of the pthread_setspecific function ----------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "pthread_setspecific.h" | ||
|
|
||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/thread.h" | ||
|
|
||
| #include <errno.h> | ||
| #include <pthread.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, pthread_setspecific, | ||
| (pthread_key_t key, const void *data)) { | ||
| if (set_tss_value(key, const_cast<void *>(data))) | ||
| return 0; | ||
| else | ||
| return EINVAL; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for pthread_setspecific function --*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_SETSPECIFIC_H | ||
| #define LLVM_LIBC_SRC_PTHREAD_PTHREAD_SETSPECIFIC_H | ||
|
|
||
| #include <pthread.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int pthread_setspecific(pthread_key_t, const void *); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_SETSPECIFIC_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| //===-- Implementation of the tss_create ----------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "tss_create.h" | ||
|
|
||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/thread.h" | ||
|
|
||
| #include <threads.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, tss_create, (tss_t * key, tss_dtor_t dtor)) { | ||
| auto k = __llvm_libc::new_tss_key(dtor); | ||
| if (!k) | ||
| return thrd_error; | ||
| *key = *k; | ||
| return thrd_success; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for tss_create --------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_THREADS_TSS_CREATE_H | ||
| #define LLVM_LIBC_SRC_THREADS_TSS_CREATE_H | ||
|
|
||
| #include <threads.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int tss_create(tss_t *key, tss_dtor_t dtor); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_THREADS_TSS_CREATE_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| //===-- Implementation of the tss_delete ----------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "tss_delete.h" | ||
|
|
||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/thread.h" | ||
|
|
||
| #include <threads.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(void, tss_delete, (tss_t key)) { | ||
| __llvm_libc::tss_key_delete(key); | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for tss_delete --------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_THREADS_TSS_DELETE_H | ||
| #define LLVM_LIBC_SRC_THREADS_TSS_DELETE_H | ||
|
|
||
| #include <threads.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| void tss_delete(tss_t key); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_THREADS_TSS_DELETE_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Linux implementation of the tss_get function ----------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "tss_get.h" | ||
|
|
||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/thread.h" | ||
|
|
||
| #include <threads.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(void *, tss_get, (tss_t key)) { return get_tss_value(key); } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for tss_get function --------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_THREADS_TSS_GET_H | ||
| #define LLVM_LIBC_SRC_THREADS_TSS_GET_H | ||
|
|
||
| #include <pthread.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| void *tss_get(pthread_key_t); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_THREADS_TSS_GET_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| //===-- Linux implementation of the tss_set function ----------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "tss_set.h" | ||
|
|
||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/thread.h" | ||
|
|
||
| #include <threads.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, tss_set, (tss_t key, void *data)) { | ||
| if (set_tss_value(key, data)) | ||
| return thrd_success; | ||
| else | ||
| return thrd_error; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for tss_set function --------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_THREADS_TSS_SET_H | ||
| #define LLVM_LIBC_SRC_THREADS_TSS_SET_H | ||
|
|
||
| #include <threads.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int tss_set(tss_t, void *); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_THREADS_TSS_SET_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| //===-- Tests for TSS API like pthread_setspecific etc. -------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "src/pthread/pthread_create.h" | ||
| #include "src/pthread/pthread_exit.h" | ||
| #include "src/pthread/pthread_getspecific.h" | ||
| #include "src/pthread/pthread_join.h" | ||
| #include "src/pthread/pthread_key_create.h" | ||
| #include "src/pthread/pthread_key_delete.h" | ||
| #include "src/pthread/pthread_setspecific.h" | ||
| #include "utils/IntegrationTest/test.h" | ||
|
|
||
| #include <pthread.h> | ||
|
|
||
| static constexpr int THREAD_DATA_INITVAL = 0x1234; | ||
| static constexpr int THREAD_DATA_FINIVAL = 0x4321; | ||
| static constexpr int THREAD_RUN_VAL = 0x600D; | ||
|
|
||
| int child_thread_data = THREAD_DATA_INITVAL; | ||
| int main_thread_data = THREAD_DATA_INITVAL; | ||
|
|
||
| pthread_key_t key; | ||
| void dtor(void *data) { | ||
| auto *v = reinterpret_cast<int *>(data); | ||
| *v = THREAD_DATA_FINIVAL; | ||
| } | ||
|
|
||
| void *func(void *obj) { | ||
| ASSERT_EQ(__llvm_libc::pthread_setspecific(key, &child_thread_data), 0); | ||
| int *d = reinterpret_cast<int *>(__llvm_libc::pthread_getspecific(key)); | ||
| ASSERT_TRUE(d != nullptr); | ||
| ASSERT_EQ(&child_thread_data, d); | ||
| ASSERT_EQ(*d, THREAD_DATA_INITVAL); | ||
| *reinterpret_cast<int *>(obj) = THREAD_RUN_VAL; | ||
| return nullptr; | ||
| } | ||
|
|
||
| TEST_MAIN() { | ||
| ASSERT_EQ(__llvm_libc::pthread_key_create(&key, &dtor), 0); | ||
| ASSERT_EQ(__llvm_libc::pthread_setspecific(key, &main_thread_data), 0); | ||
| int *d = reinterpret_cast<int *>(__llvm_libc::pthread_getspecific(key)); | ||
| ASSERT_TRUE(d != nullptr); | ||
| ASSERT_EQ(&main_thread_data, d); | ||
| ASSERT_EQ(*d, THREAD_DATA_INITVAL); | ||
|
|
||
| pthread_t th; | ||
| int arg = 0xBAD; | ||
| ASSERT_EQ(__llvm_libc::pthread_create(&th, nullptr, &func, &arg), 0); | ||
| void *retval = &child_thread_data; // Init to some non-nullptr val. | ||
| ASSERT_EQ(__llvm_libc::pthread_join(th, &retval), 0); | ||
| ASSERT_EQ(retval, nullptr); | ||
| ASSERT_EQ(arg, THREAD_RUN_VAL); | ||
| ASSERT_EQ(child_thread_data, THREAD_DATA_FINIVAL); | ||
|
|
||
| ASSERT_EQ(__llvm_libc::pthread_key_delete(key), 0); | ||
| return 0; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| //===-- Tests for TSS API like tss_set, tss_get etc. ----------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "src/threads/thrd_create.h" | ||
| #include "src/threads/thrd_exit.h" | ||
| #include "src/threads/thrd_join.h" | ||
| #include "src/threads/tss_create.h" | ||
| #include "src/threads/tss_delete.h" | ||
| #include "src/threads/tss_get.h" | ||
| #include "src/threads/tss_set.h" | ||
| #include "utils/IntegrationTest/test.h" | ||
|
|
||
| #include <threads.h> | ||
|
|
||
| static constexpr int THREAD_DATA_INITVAL = 0x1234; | ||
| static constexpr int THREAD_DATA_FINIVAL = 0x4321; | ||
| static constexpr int THREAD_RUN_VAL = 0x600D; | ||
|
|
||
| int child_thread_data = THREAD_DATA_INITVAL; | ||
| int main_thread_data = THREAD_DATA_INITVAL; | ||
|
|
||
| tss_t key; | ||
| void dtor(void *data) { | ||
| auto *v = reinterpret_cast<int *>(data); | ||
| *v = THREAD_DATA_FINIVAL; | ||
| } | ||
|
|
||
| int func(void *obj) { | ||
| ASSERT_EQ(__llvm_libc::tss_set(key, &child_thread_data), thrd_success); | ||
| int *d = reinterpret_cast<int *>(__llvm_libc::tss_get(key)); | ||
| ASSERT_TRUE(d != nullptr); | ||
| ASSERT_EQ(&child_thread_data, d); | ||
| ASSERT_EQ(*d, THREAD_DATA_INITVAL); | ||
| *reinterpret_cast<int *>(obj) = THREAD_RUN_VAL; | ||
| return 0; | ||
| } | ||
|
|
||
| TEST_MAIN() { | ||
| ASSERT_EQ(__llvm_libc::tss_create(&key, &dtor), thrd_success); | ||
| ASSERT_EQ(__llvm_libc::tss_set(key, &main_thread_data), thrd_success); | ||
| int *d = reinterpret_cast<int *>(__llvm_libc::tss_get(key)); | ||
| ASSERT_TRUE(d != nullptr); | ||
| ASSERT_EQ(&main_thread_data, d); | ||
| ASSERT_EQ(*d, THREAD_DATA_INITVAL); | ||
|
|
||
| thrd_t th; | ||
| int arg = 0xBAD; | ||
| ASSERT_EQ(__llvm_libc::thrd_create(&th, &func, &arg), thrd_success); | ||
| int retval = THREAD_DATA_INITVAL; // Init to some non-zero val. | ||
| ASSERT_EQ(__llvm_libc::thrd_join(th, &retval), thrd_success); | ||
| ASSERT_EQ(retval, 0); | ||
| ASSERT_EQ(arg, THREAD_RUN_VAL); | ||
| ASSERT_EQ(child_thread_data, THREAD_DATA_FINIVAL); | ||
|
|
||
| __llvm_libc::tss_delete(key); | ||
|
|
||
| return 0; | ||
| } |