[libc-commits] [libc] 70c8d12 - [libc] Add pthread_create and pthread_join functions.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Wed Jun 1 18:47:54 PDT 2022
Author: Siva Chandra Reddy
Date: 2022-06-02T01:47:24Z
New Revision: 70c8d12b79a58cf350256bb0a366f0e91000d82e
URL: https://github.com/llvm/llvm-project/commit/70c8d12b79a58cf350256bb0a366f0e91000d82e
DIFF: https://github.com/llvm/llvm-project/commit/70c8d12b79a58cf350256bb0a366f0e91000d82e.diff
LOG: [libc] Add pthread_create and pthread_join functions.
They do not yet support all the feature/attributes in pthread_attr_t.
Future changes will add such support.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D126718
Added:
libc/include/llvm-libc-types/__pthread_start_t.h
libc/include/llvm-libc-types/__thread_type.h
libc/include/llvm-libc-types/pthread_t.h
libc/src/pthread/pthread_create.cpp
libc/src/pthread/pthread_create.h
libc/src/pthread/pthread_join.cpp
libc/src/pthread/pthread_join.h
libc/test/src/pthread/pthread_test.cpp
Modified:
libc/config/linux/api.td
libc/config/linux/x86_64/entrypoints.txt
libc/include/CMakeLists.txt
libc/include/llvm-libc-types/CMakeLists.txt
libc/include/llvm-libc-types/thrd_t.h
libc/spec/posix.td
libc/src/pthread/CMakeLists.txt
libc/test/src/pthread/CMakeLists.txt
libc/test/src/pthread/pthread_mutex_test.cpp
Removed:
################################################################################
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index f8ca32133eea8..3ab2f3a63a724 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -244,9 +244,11 @@ def ThreadsAPI : PublicAPI<"threads.h"> {
def PThreadAPI : PublicAPI<"pthread.h"> {
let Types = [
+ "__pthread_start_t",
"pthread_attr_t",
"pthread_mutex_t",
- "pthread_mutexattr_t"
+ "pthread_mutexattr_t",
+ "pthread_t",
];
}
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 28607d615edcb..ed2e248d7652c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -236,6 +236,8 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.pthread.pthread_attr_setstack
libc.src.pthread.pthread_attr_setstacksize
libc.src.pthread.pthread_attr_init
+ libc.src.pthread.pthread_create
+ libc.src.pthread.pthread_join
libc.src.pthread.pthread_mutex_destroy
libc.src.pthread.pthread_mutex_init
libc.src.pthread.pthread_mutex_lock
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 5ffef44cbc62e..afd4972120d4a 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -162,9 +162,11 @@ add_gen_header(
GEN_HDR pthread.h
DEPENDS
.llvm_libc_common_h
+ .llvm-libc-types.__pthread_start_t
.llvm-libc-types.pthread_attr_t
.llvm-libc-types.pthread_mutex_t
.llvm-libc-types.pthread_mutexattr_t
+ .llvm-libc-types.pthread_t
)
# TODO: Not all platforms will have a include/sys directory. Add the sys
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 681f7aa63fd28..9ca82ad811282 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -1,9 +1,11 @@
add_header(__bsearchcompare_t HDR __bsearchcompare_t.h)
add_header(__call_once_func_t HDR __call_once_func_t.h)
add_header(__futex_word HDR __futex_word.h)
-add_header(__mutex_type HDR __mutex_type.h)
+add_header(__mutex_type HDR __mutex_type.h DEPENDS .__futex_word)
+add_header(__pthread_start_t HDR __pthread_start_t.h)
add_header(__qsortcompare_t HDR __qsortcompare_t.h)
add_header(__sighandler_t HDR __sighandler_t.h)
+add_header(__thread_type HDR __thread_type.h)
add_header(cnd_t HDR cnd_t.h)
add_header(cookie_io_functions_t HDR cookie_io_functions_t.h DEPENDS .off64_t)
add_header(double_t HDR double_t.h)
@@ -22,12 +24,13 @@ add_header(off64_t HDR off64_t.h)
add_header(once_flag HDR once_flag.h DEPENDS .__futex_word)
add_header(pthread_attr_t HDR pthread_attr_t.h DEPENDS .size_t)
add_header(pthread_mutex_t HDR pthread_mutex_t.h DEPENDS .__futex_word .__mutex_type)
+add_header(pthread_t HDR pthread_t.h DEPENDS .__thread_type)
add_header(pthread_mutexattr_t HDR pthread_mutexattr_t.h)
add_header(size_t HDR size_t.h)
add_header(ssize_t HDR ssize_t.h)
add_header(struct_sigaction HDR struct_sigaction.h)
add_header(struct_tm HDR struct_tm.h)
add_header(thrd_start_t HDR thrd_start_t.h)
-add_header(thrd_t HDR thrd_t.h)
+add_header(thrd_t HDR thrd_t.h DEPENDS .__thread_type)
add_header(time_t HDR time_t.h)
add_header(__atexithandler_t HDR __atexithandler_t.h)
diff --git a/libc/include/llvm-libc-types/__pthread_start_t.h b/libc/include/llvm-libc-types/__pthread_start_t.h
new file mode 100644
index 0000000000000..1e05f9b497299
--- /dev/null
+++ b/libc/include/llvm-libc-types/__pthread_start_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of __pthread_start_t type ------------------------------===//
+//
+// 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_TYPES_PTHREAD_START_T_H__
+#define __LLVM_LIBC_TYPES_PTHREAD_START_T_H__
+
+typedef void *(*__pthread_start_t)(void *);
+
+#endif // __LLVM_LIBC_TYPES_PTHREAD_START_T_H__
diff --git a/libc/include/llvm-libc-types/__thread_type.h b/libc/include/llvm-libc-types/__thread_type.h
new file mode 100644
index 0000000000000..1d64f909bd809
--- /dev/null
+++ b/libc/include/llvm-libc-types/__thread_type.h
@@ -0,0 +1,17 @@
+//===-- Definition of thrd_t type -----------------------------------------===//
+//
+// 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_TYPES_THREAD_TYPE_H__
+#define __LLVM_LIBC_TYPES_THREAD_TYPE_H__
+
+typedef struct {
+ void *__attrib;
+ void *__platform_attrib;
+} __thread_type;
+
+#endif // __LLVM_LIBC_TYPES_THREAD_TYPE_H__
diff --git a/libc/include/llvm-libc-types/pthread_t.h b/libc/include/llvm-libc-types/pthread_t.h
new file mode 100644
index 0000000000000..8130491274efb
--- /dev/null
+++ b/libc/include/llvm-libc-types/pthread_t.h
@@ -0,0 +1,16 @@
+//===-- Definition of pthread_t type --------------------------------------===//
+//
+// 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_TYPES_PTHREAD_T_H__
+#define __LLVM_LIBC_TYPES_PTHREAD_T_H__
+
+#include <llvm-libc-types/__thread_type.h>
+
+typedef __thread_type pthread_t;
+
+#endif // __LLVM_LIBC_TYPES_PTHREAD_T_H__
diff --git a/libc/include/llvm-libc-types/thrd_t.h b/libc/include/llvm-libc-types/thrd_t.h
index 169f937042c6b..0743106c48c64 100644
--- a/libc/include/llvm-libc-types/thrd_t.h
+++ b/libc/include/llvm-libc-types/thrd_t.h
@@ -9,11 +9,8 @@
#ifndef __LLVM_LIBC_TYPES_THRD_T_H__
#define __LLVM_LIBC_TYPES_THRD_T_H__
-#include <llvm-libc-types/__futex_word.h>
+#include <llvm-libc-types/__thread_type.h>
-typedef struct {
- void *__attribs;
- void *__platform_attribs;
-} thrd_t;
+typedef __thread_type thrd_t;
#endif // __LLVM_LIBC_TYPES_THRD_T_H__
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index 2436d8eea4b1c..e53942dd850c4 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -10,6 +10,8 @@ def ConstStructSigactionPtr : ConstType<StructSigactionPtr>;
def RestrictedStructSigactionPtr : RestrictedPtrType<StructSigaction>;
def ConstRestrictedStructSigactionPtr : ConstType<RestrictedStructSigactionPtr>;
+def PThreadStartT : NamedType<"__pthread_start_t">;
+
def POSIX : StandardSpec<"POSIX"> {
PtrType CharPtr = PtrType<CharType>;
RestrictedPtrType RestrictedCharPtr = RestrictedPtrType<CharType>;
@@ -39,6 +41,10 @@ def POSIX : StandardSpec<"POSIX"> {
ConstType ConstPThreadMutexTPtr = ConstType<PThreadMutexTPtr>;
ConstType ConstRestrictedPThreadMutexTPtr = ConstType<RestrictedPThreadMutexTPtr>;
+ NamedType PThreadTType = NamedType<"pthread_t">;
+ PtrType PThreadTPtr = PtrType<PThreadTType>;
+ RestrictedPtrType RestrictedPThreadTPtr = RestrictedPtrType<PThreadTType>;
+
HeaderSpec Errno = HeaderSpec<
"errno.h",
[
@@ -392,7 +398,7 @@ def POSIX : StandardSpec<"POSIX"> {
HeaderSpec PThread = HeaderSpec<
"pthread.h",
[], // Macros
- [PThreadAttrTType, PThreadMutexAttrTType, PThreadMutexTType], // Types
+ [PThreadAttrTType, PThreadMutexAttrTType, PThreadMutexTType, PThreadStartT, PThreadTType], // Types
[], // Enumerations
[
FunctionSpec<
@@ -445,6 +451,16 @@ def POSIX : StandardSpec<"POSIX"> {
RetValSpec<IntType>,
[ArgSpec<PThreadAttrTPtr>, ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
>,
+ FunctionSpec<
+ "pthread_create",
+ RetValSpec<IntType>,
+ [ArgSpec<RestrictedPThreadTPtr>, ArgSpec<ConstRestrictedPThreadAttrTPtr>, ArgSpec<PThreadStartT>, ArgSpec<VoidPtr>]
+ >,
+ FunctionSpec<
+ "pthread_join",
+ RetValSpec<IntType>,
+ [ArgSpec<PThreadTType>, ArgSpec<VoidPtrPtr>]
+ >,
FunctionSpec<
"pthread_mutexattr_init",
RetValSpec<IntType>,
diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt
index ca5f0e0433cb5..828fee219a5c1 100644
--- a/libc/src/pthread/CMakeLists.txt
+++ b/libc/src/pthread/CMakeLists.txt
@@ -242,3 +242,26 @@ add_entrypoint_object(
libc.include.pthread
libc.src.__support.threads.mutex
)
+
+add_entrypoint_object(
+ pthread_create
+ SRCS
+ pthread_create.cpp
+ HDRS
+ pthread_create.h
+ DEPENDS
+ libc.include.errno
+ libc.include.pthread
+ libc.src.__support.threads.thread
+)
+
+add_entrypoint_object(
+ pthread_join
+ SRCS
+ pthread_join.cpp
+ HDRS
+ pthread_join.h
+ DEPENDS
+ libc.include.pthread
+ libc.src.__support.threads.thread
+)
diff --git a/libc/src/pthread/pthread_create.cpp b/libc/src/pthread/pthread_create.cpp
new file mode 100644
index 0000000000000..bc945a93984e9
--- /dev/null
+++ b/libc/src/pthread/pthread_create.cpp
@@ -0,0 +1,33 @@
+//===-- Linux implementation of the pthread_create 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_create.h"
+
+#include "src/__support/common.h"
+#include "src/__support/threads/thread.h"
+
+#include <errno.h>
+#include <pthread.h> // For pthread_* type definitions.
+
+namespace __llvm_libc {
+
+static_assert(sizeof(pthread_t) == sizeof(__llvm_libc::Thread<int>),
+ "Mismatch between pthread_t and internal Thread<int>.");
+
+LLVM_LIBC_FUNCTION(int, pthread_create,
+ (pthread_t *__restrict th,
+ const pthread_attr_t *__restrict attr,
+ __pthread_start_t func, void *arg)) {
+ auto *thread = reinterpret_cast<__llvm_libc::Thread<void *> *>(th);
+ int result = thread->run(func, arg, nullptr, 0);
+ if (result != 0 && result != EPERM)
+ return EAGAIN;
+ return result;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_create.h b/libc/src/pthread/pthread_create.h
new file mode 100644
index 0000000000000..500aa6cc8138e
--- /dev/null
+++ b/libc/src/pthread/pthread_create.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for pthread_create 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_PTHREAD_CREATE_H
+#define LLVM_LIBC_SRC_THREADS_PTHREAD_CREATE_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_create(pthread_t *__restrict thread,
+ const pthread_attr_t *__restrict attr,
+ __pthread_start_t func, void *arg);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_THREADS_PTHREAD_CREATE_H
diff --git a/libc/src/pthread/pthread_join.cpp b/libc/src/pthread/pthread_join.cpp
new file mode 100644
index 0000000000000..c3bf4adc6372e
--- /dev/null
+++ b/libc/src/pthread/pthread_join.cpp
@@ -0,0 +1,27 @@
+//===-- Linux implementation of the pthread_join 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_join.h"
+
+#include "src/__support/common.h"
+#include "src/__support/threads/thread.h"
+
+#include <pthread.h> // For pthread_* type definitions.
+
+namespace __llvm_libc {
+
+static_assert(sizeof(pthread_t) == sizeof(__llvm_libc::Thread<int>),
+ "Mismatch between pthread_t and internal Thread<int>.");
+
+LLVM_LIBC_FUNCTION(int, pthread_join, (pthread_t th, void **retval)) {
+ auto *thread = reinterpret_cast<Thread<void *> *>(&th);
+ int result = thread->join(retval);
+ return result;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_join.h b/libc/src/pthread/pthread_join.h
new file mode 100644
index 0000000000000..d659897b07377
--- /dev/null
+++ b/libc/src/pthread/pthread_join.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_join 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_PTHREAD_JOIN_H
+#define LLVM_LIBC_SRC_THREADS_PTHREAD_JOIN_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_join(pthread_t thread, void **retval);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_THREADS_PTHREAD_JOIN_H
diff --git a/libc/test/src/pthread/CMakeLists.txt b/libc/test/src/pthread/CMakeLists.txt
index 5f3bbcbdd9a36..f69c77fd4c3ec 100644
--- a/libc/test/src/pthread/CMakeLists.txt
+++ b/libc/test/src/pthread/CMakeLists.txt
@@ -41,7 +41,7 @@ add_libc_unittest(
)
add_libc_unittest(
- phtread_mutex_test
+ pthread_mutex_test
SUITE
libc_pthread_unittests
SRCS
@@ -53,6 +53,18 @@ add_libc_unittest(
libc.src.pthread.pthread_mutex_init
libc.src.pthread.pthread_mutex_lock
libc.src.pthread.pthread_mutex_unlock
- libc.src.threads.thrd_create
- libc.src.threads.thrd_join
+ libc.src.pthread.pthread_create
+ libc.src.pthread.pthread_join
+)
+
+add_libc_unittest(
+ pthread_test
+ SUITE
+ libc_pthread_unittests
+ SRCS
+ pthread_test.cpp
+ DEPENDS
+ libc.include.pthread
+ libc.src.pthread.pthread_create
+ libc.src.pthread.pthread_join
)
diff --git a/libc/test/src/pthread/pthread_mutex_test.cpp b/libc/test/src/pthread/pthread_mutex_test.cpp
index 8b06294169ed6..28c06b01eb1a1 100644
--- a/libc/test/src/pthread/pthread_mutex_test.cpp
+++ b/libc/test/src/pthread/pthread_mutex_test.cpp
@@ -11,10 +11,8 @@
#include "src/pthread/pthread_mutex_lock.h"
#include "src/pthread/pthread_mutex_unlock.h"
-// TODO: When pthread_t type is available, use it to spawn threads instead of
-// thrd_t.
-#include "src/threads/thrd_create.h"
-#include "src/threads/thrd_join.h"
+#include "src/pthread/pthread_create.h"
+#include "src/pthread/pthread_join.h"
#include "utils/UnitTest/Test.h"
@@ -26,7 +24,7 @@ constexpr int MAX = 10000;
pthread_mutex_t mutex;
static int shared_int = START;
-int counter(void *arg) {
+void *counter(void *arg) {
int last_count = START;
while (true) {
__llvm_libc::pthread_mutex_lock(&mutex);
@@ -38,7 +36,7 @@ int counter(void *arg) {
if (last_count >= MAX)
break;
}
- return 0;
+ return nullptr;
}
TEST(LlvmLibcMutexTest, RelayCounter) {
@@ -46,8 +44,8 @@ TEST(LlvmLibcMutexTest, RelayCounter) {
// The idea of this test is that two competing threads will update
// a counter only if the other thread has updated it.
- thrd_t thread;
- __llvm_libc::thrd_create(&thread, counter, nullptr);
+ pthread_t thread;
+ __llvm_libc::pthread_create(&thread, nullptr, counter, nullptr);
int last_count = START;
while (true) {
@@ -65,9 +63,9 @@ TEST(LlvmLibcMutexTest, RelayCounter) {
break;
}
- int retval = 123;
- __llvm_libc::thrd_join(&thread, &retval);
- ASSERT_EQ(retval, 0);
+ void *retval = reinterpret_cast<void *>(123);
+ __llvm_libc::pthread_join(thread, &retval);
+ ASSERT_EQ(uintptr_t(retval), uintptr_t(nullptr));
__llvm_libc::pthread_mutex_destroy(&mutex);
}
@@ -75,7 +73,7 @@ TEST(LlvmLibcMutexTest, RelayCounter) {
pthread_mutex_t start_lock, step_lock;
bool started, step;
-int stepper(void *arg) {
+void *stepper(void *arg) {
__llvm_libc::pthread_mutex_lock(&start_lock);
started = true;
__llvm_libc::pthread_mutex_unlock(&start_lock);
@@ -83,7 +81,7 @@ int stepper(void *arg) {
__llvm_libc::pthread_mutex_lock(&step_lock);
step = true;
__llvm_libc::pthread_mutex_unlock(&step_lock);
- return 0;
+ return nullptr;
}
TEST(LlvmLibcMutexTest, WaitAndStep) {
@@ -97,8 +95,8 @@ TEST(LlvmLibcMutexTest, WaitAndStep) {
started = false;
ASSERT_EQ(__llvm_libc::pthread_mutex_lock(&step_lock), 0);
- thrd_t thread;
- __llvm_libc::thrd_create(&thread, stepper, nullptr);
+ pthread_t thread;
+ __llvm_libc::pthread_create(&thread, nullptr, stepper, nullptr);
while (true) {
// Make sure the thread actually started.
@@ -123,9 +121,9 @@ TEST(LlvmLibcMutexTest, WaitAndStep) {
break;
}
- int retval = 123;
- __llvm_libc::thrd_join(&thread, &retval);
- ASSERT_EQ(retval, 0);
+ void *retval = reinterpret_cast<void *>(123);
+ __llvm_libc::pthread_join(thread, &retval);
+ ASSERT_EQ(uintptr_t(retval), uintptr_t(nullptr));
__llvm_libc::pthread_mutex_destroy(&start_lock);
__llvm_libc::pthread_mutex_destroy(&step_lock);
@@ -136,7 +134,7 @@ static pthread_mutex_t multiple_waiter_lock;
static pthread_mutex_t counter_lock;
static int wait_count = 0;
-int waiter_func(void *) {
+void *waiter_func(void *) {
__llvm_libc::pthread_mutex_lock(&counter_lock);
++wait_count;
__llvm_libc::pthread_mutex_unlock(&counter_lock);
@@ -150,7 +148,7 @@ int waiter_func(void *) {
--wait_count;
__llvm_libc::pthread_mutex_unlock(&counter_lock);
- return 0;
+ return nullptr;
}
TEST(LlvmLibcMutexTest, MultipleWaiters) {
@@ -158,9 +156,9 @@ TEST(LlvmLibcMutexTest, MultipleWaiters) {
__llvm_libc::pthread_mutex_init(&counter_lock, nullptr);
__llvm_libc::pthread_mutex_lock(&multiple_waiter_lock);
- thrd_t waiters[THREAD_COUNT];
+ pthread_t waiters[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; ++i) {
- __llvm_libc::thrd_create(waiters + i, waiter_func, nullptr);
+ __llvm_libc::pthread_create(waiters + i, nullptr, waiter_func, nullptr);
}
// Spin until the counter is incremented to the desired
@@ -176,9 +174,9 @@ TEST(LlvmLibcMutexTest, MultipleWaiters) {
__llvm_libc::pthread_mutex_unlock(&multiple_waiter_lock);
- int retval;
+ void *retval;
for (int i = 0; i < THREAD_COUNT; ++i) {
- __llvm_libc::thrd_join(waiters + i, &retval);
+ __llvm_libc::pthread_join(waiters[i], &retval);
}
ASSERT_EQ(wait_count, 0);
diff --git a/libc/test/src/pthread/pthread_test.cpp b/libc/test/src/pthread/pthread_test.cpp
new file mode 100644
index 0000000000000..3a3d587ab5d51
--- /dev/null
+++ b/libc/test/src/pthread/pthread_test.cpp
@@ -0,0 +1,56 @@
+//===-- Unittests for pthread_t -------------------------------------------===//
+//
+// 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_join.h"
+#include "utils/UnitTest/Test.h"
+
+#include <pthread.h>
+
+static constexpr int thread_count = 1000;
+static int counter = 0;
+static void *thread_func(void *) {
+ ++counter;
+ return nullptr;
+}
+
+TEST(LlvmLibcThreadTest, CreateAndJoin) {
+ for (counter = 0; counter <= thread_count;) {
+ pthread_t thread;
+ int old_counter_val = counter;
+ ASSERT_EQ(
+ __llvm_libc::pthread_create(&thread, nullptr, thread_func, nullptr), 0);
+
+ // Start with a retval we dont expect.
+ void *retval = reinterpret_cast<void *>(thread_count + 1);
+ ASSERT_EQ(__llvm_libc::pthread_join(thread, &retval), 0);
+ ASSERT_EQ(uintptr_t(retval), uintptr_t(nullptr));
+ ASSERT_EQ(counter, old_counter_val + 1);
+ }
+}
+
+static void *return_arg(void *arg) { return arg; }
+
+TEST(LlvmLibcThreadTest, SpawnAndJoin) {
+ pthread_t thread_list[thread_count];
+ int args[thread_count];
+
+ for (int i = 0; i < thread_count; ++i) {
+ args[i] = i;
+ ASSERT_EQ(__llvm_libc::pthread_create(thread_list + i, nullptr, return_arg,
+ args + i),
+ 0);
+ }
+
+ for (int i = 0; i < thread_count; ++i) {
+ // Start with a retval we dont expect.
+ void *retval = reinterpret_cast<void *>(thread_count + 1);
+ ASSERT_EQ(__llvm_libc::pthread_join(thread_list[i], &retval), 0);
+ ASSERT_EQ(*reinterpret_cast<int *>(retval), i);
+ }
+}
More information about the libc-commits
mailing list