Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorSiva Chandra Reddy <sivachandra@google.com>2022-04-08 11:07:22 +0300
committerSiva Chandra Reddy <sivachandra@google.com>2022-04-11 19:08:49 +0300
commit0258f566466268704caa2476f20e4a87a6257d06 (patch)
treec4d958a5f2881305de83c67bceab39d63697f3f7 /libc
parent1c8366f9f2aa436538949aa2b76f96980bb0de27 (diff)
[libc] Add a definition of pthread_attr_t and its getters and setters.
Not all attributes have been added to phtread_attr_t in this patch. They will be added gradually in future patches. Reviewed By: lntue Differential Revision: https://reviews.llvm.org/D123423
Diffstat (limited to 'libc')
-rw-r--r--libc/config/linux/aarch64/entrypoints.txt10
-rw-r--r--libc/config/linux/api.td5
-rw-r--r--libc/config/linux/x86_64/entrypoints.txt11
-rw-r--r--libc/include/CMakeLists.txt1
-rw-r--r--libc/include/llvm-libc-types/CMakeLists.txt1
-rw-r--r--libc/include/llvm-libc-types/pthread_attr_t.h21
-rw-r--r--libc/include/pthread.h.def5
-rw-r--r--libc/spec/posix.td59
-rw-r--r--libc/spec/spec.td6
-rw-r--r--libc/src/pthread/CMakeLists.txt100
-rw-r--r--libc/src/pthread/pthread_attr_destroy.cpp22
-rw-r--r--libc/src/pthread/pthread_attr_destroy.h20
-rw-r--r--libc/src/pthread/pthread_attr_getdetachstate.cpp23
-rw-r--r--libc/src/pthread/pthread_attr_getdetachstate.h20
-rw-r--r--libc/src/pthread/pthread_attr_getguardsize.cpp24
-rw-r--r--libc/src/pthread/pthread_attr_getguardsize.h21
-rw-r--r--libc/src/pthread/pthread_attr_getstack.cpp25
-rw-r--r--libc/src/pthread/pthread_attr_getstack.h22
-rw-r--r--libc/src/pthread/pthread_attr_getstacksize.cpp24
-rw-r--r--libc/src/pthread/pthread_attr_getstacksize.h21
-rw-r--r--libc/src/pthread/pthread_attr_init.cpp28
-rw-r--r--libc/src/pthread/pthread_attr_init.h20
-rw-r--r--libc/src/pthread/pthread_attr_setdetachstate.cpp27
-rw-r--r--libc/src/pthread/pthread_attr_setdetachstate.h20
-rw-r--r--libc/src/pthread/pthread_attr_setguardsize.cpp27
-rw-r--r--libc/src/pthread/pthread_attr_setguardsize.h20
-rw-r--r--libc/src/pthread/pthread_attr_setstack.cpp33
-rw-r--r--libc/src/pthread/pthread_attr_setstack.h20
-rw-r--r--libc/src/pthread/pthread_attr_setstacksize.cpp28
-rw-r--r--libc/src/pthread/pthread_attr_setstacksize.h20
-rw-r--r--libc/test/src/pthread/CMakeLists.txt21
-rw-r--r--libc/test/src/pthread/pthread_attr_test.cpp113
32 files changed, 816 insertions, 2 deletions
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index aa66c0d040a4..eaedb4237ed1 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -230,6 +230,16 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.threads.thrd_join
# pthread.h entrypoints
+ libc.src.pthread.pthread_attr_destroy
+ libc.src.pthread.pthread_attr_init
+ libc.src.pthread.pthread_attr_getdetachstate
+ libc.src.pthread.pthread_attr_getguardsize
+ libc.src.pthread.pthread_attr_getstack
+ libc.src.pthread.pthread_attr_getstacksize
+ libc.src.pthread.pthread_attr_setdetachstate
+ libc.src.pthread.pthread_attr_setguardsize
+ libc.src.pthread.pthread_attr_setstack
+ libc.src.pthread.pthread_attr_setstacksize
libc.src.pthread.pthread_mutexattr_destroy
libc.src.pthread.pthread_mutexattr_init
libc.src.pthread.pthread_mutexattr_getpshared
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 9d2f142ef43a..ed2b3b6b4ece 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -238,7 +238,10 @@ def ThreadsAPI : PublicAPI<"threads.h"> {
}
def PThreadAPI : PublicAPI<"pthread.h"> {
- let Types = ["pthread_mutexattr_t"];
+ let Types = [
+ "pthread_attr_t",
+ "pthread_mutexattr_t"
+ ];
}
def UniStdAPI : PublicAPI<"unistd.h"> {
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index c5c5e5046de2..5fc5d19f7520 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -223,6 +223,17 @@ if(LLVM_LIBC_FULL_BUILD)
# libc.src.assert.__assert_fail
# pthread.h entrypoints
+ libc.src.pthread.pthread_attr_destroy
+ libc.src.pthread.pthread_attr_init
+ libc.src.pthread.pthread_attr_getdetachstate
+ libc.src.pthread.pthread_attr_getguardsize
+ libc.src.pthread.pthread_attr_getstack
+ libc.src.pthread.pthread_attr_getstacksize
+ libc.src.pthread.pthread_attr_setdetachstate
+ libc.src.pthread.pthread_attr_setguardsize
+ libc.src.pthread.pthread_attr_setstack
+ libc.src.pthread.pthread_attr_setstacksize
+ libc.src.pthread.pthread_attr_init
libc.src.pthread.pthread_mutexattr_destroy
libc.src.pthread.pthread_mutexattr_init
libc.src.pthread.pthread_mutexattr_getpshared
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index efe9e8107ee7..9a4a888bd2d7 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -161,6 +161,7 @@ add_gen_header(
GEN_HDR pthread.h
DEPENDS
.llvm_libc_common_h
+ .llvm-libc-types.pthread_attr_t
.llvm-libc-types.pthread_mutexattr_t
)
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 77a86fe25619..9ddeeb73f499 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -18,6 +18,7 @@ add_header(mode_t HDR mode_t.h)
add_header(mtx_t HDR mtx_t.h DEPENDS .__futex_word .__mutex_type)
add_header(off_t HDR off_t.h)
add_header(once_flag HDR once_flag.h DEPENDS .__futex_word)
+add_header(pthread_attr_t HDR pthread_attr_t.h)
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)
diff --git a/libc/include/llvm-libc-types/pthread_attr_t.h b/libc/include/llvm-libc-types/pthread_attr_t.h
new file mode 100644
index 000000000000..7bf8a5402f28
--- /dev/null
+++ b/libc/include/llvm-libc-types/pthread_attr_t.h
@@ -0,0 +1,21 @@
+//===-- Definition of pthread_attr_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_ATTR_T_H
+#define __LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
+
+#include <llvm-libc-types/size_t.h>
+
+typedef struct {
+ int __detachstate;
+ void *__stack;
+ size_t __stacksize;
+ size_t __guardsize;
+} pthread_attr_t;
+
+#endif // __LLVM_LIBC_TYPES_PTHREAD_ATTR_T_H
diff --git a/libc/include/pthread.h.def b/libc/include/pthread.h.def
index 9de3da4b5dee..60f257e7078d 100644
--- a/libc/include/pthread.h.def
+++ b/libc/include/pthread.h.def
@@ -11,7 +11,12 @@
#include <__llvm-libc-common.h>
+#define PTHREAD_STACK_MIN (1 << 14) // 16KB
+
enum {
+ PTHREAD_CREATE_JOINABLE = 0x0,
+ PTHREAD_CREATE_DETACHED = 0x1,
+
PTHREAD_MUTEX_NORMAL = 0x0,
PTHREAD_MUTEX_ERRORCHECK = 0x1,
PTHREAD_MUTEX_RECURSIVE = 0x2,
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index 882ccf5e6d72..13b4ed4ce49d 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -20,6 +20,13 @@ def POSIX : StandardSpec<"POSIX"> {
NamedType ModeTType = NamedType<"mode_t">;
NamedType OffTType = NamedType<"off_t">;
NamedType SSizeTType = NamedType<"ssize_t">;
+
+ NamedType PThreadAttrTType = NamedType<"pthread_attr_t">;
+ PtrType PThreadAttrTPtr = PtrType<PThreadAttrTType>;
+ RestrictedPtrType RestrictedPThreadAttrTPtr = RestrictedPtrType<PThreadAttrTType>;
+ ConstType ConstPThreadAttrTPtr = ConstType<PThreadAttrTPtr>;
+ ConstType ConstRestrictedPThreadAttrTPtr = ConstType<RestrictedPThreadAttrTPtr>;
+
NamedType PThreadMutexAttrTType = NamedType<"pthread_mutexattr_t">;
PtrType PThreadMutexAttrTPtr = PtrType<PThreadMutexAttrTType>;
RestrictedPtrType RestrictedPThreadMutexAttrTPtr = RestrictedPtrType<PThreadMutexAttrTType>;
@@ -379,10 +386,60 @@ def POSIX : StandardSpec<"POSIX"> {
HeaderSpec PThread = HeaderSpec<
"pthread.h",
[], // Macros
- [PThreadMutexAttrTType], // Types
+ [PThreadAttrTType, PThreadMutexAttrTType], // Types
[], // Enumerations
[
FunctionSpec<
+ "pthread_attr_init",
+ RetValSpec<IntType>,
+ [ArgSpec<PThreadAttrTPtr>]
+ >,
+ FunctionSpec<
+ "pthread_attr_destroy",
+ RetValSpec<IntType>,
+ [ArgSpec<PThreadAttrTPtr>]
+ >,
+ FunctionSpec<
+ "pthread_attr_getdetachstate",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstPThreadAttrTPtr>, ArgSpec<IntPtr>]
+ >,
+ FunctionSpec<
+ "pthread_attr_setdetachstate",
+ RetValSpec<IntType>,
+ [ArgSpec<PThreadAttrTPtr>, ArgSpec<IntType>]
+ >,
+ FunctionSpec<
+ "pthread_attr_getguardsize",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstRestrictedPThreadAttrTPtr>, ArgSpec<RestrictedSizeTPtr>]
+ >,
+ FunctionSpec<
+ "pthread_attr_setguardsize",
+ RetValSpec<IntType>,
+ [ArgSpec<PThreadAttrTPtr>, ArgSpec<SizeTType>]
+ >,
+ FunctionSpec<
+ "pthread_attr_getstacksize",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstRestrictedPThreadAttrTPtr>, ArgSpec<RestrictedSizeTPtr>]
+ >,
+ FunctionSpec<
+ "pthread_attr_setstacksize",
+ RetValSpec<IntType>,
+ [ArgSpec<PThreadAttrTPtr>, ArgSpec<SizeTType>]
+ >,
+ FunctionSpec<
+ "pthread_attr_getstack",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstRestrictedPThreadAttrTPtr>, ArgSpec<RestrictedVoidPtrPtr>, ArgSpec<RestrictedSizeTPtr>]
+ >,
+ FunctionSpec<
+ "pthread_attr_setstack",
+ RetValSpec<IntType>,
+ [ArgSpec<PThreadAttrTPtr>, ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
+ >,
+ FunctionSpec<
"pthread_mutexattr_init",
RetValSpec<IntType>,
[ArgSpec<PThreadMutexAttrTPtr>]
diff --git a/libc/spec/spec.td b/libc/spec/spec.td
index 2261043a726c..5c947e4a17ca 100644
--- a/libc/spec/spec.td
+++ b/libc/spec/spec.td
@@ -50,8 +50,14 @@ def CharType : NamedType<"char">;
// Common types
def VoidPtr : PtrType<VoidType>;
+def VoidPtrPtr : PtrType<VoidPtr>;
+def RestrictedVoidPtrPtr : RestrictedPtrType<VoidPtr>;
def ConstVoidPtr : ConstType<VoidPtr>;
+
def SizeTType : NamedType<"size_t">;
+def SizeTPtr : PtrType<SizeTType>;
+def RestrictedSizeTPtr : RestrictedPtrType<SizeTType>;
+
def LongDoublePtr : PtrType<LongDoubleType>;
def IntMaxTType : NamedType<"intmax_t">;
diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt
index 22d61c85af27..5d447baef08a 100644
--- a/libc/src/pthread/CMakeLists.txt
+++ b/libc/src/pthread/CMakeLists.txt
@@ -1,3 +1,103 @@
+add_entrypoint_object(
+ pthread_attr_init
+ SRCS
+ pthread_attr_init.cpp
+ HDRS
+ pthread_attr_init.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_destroy
+ SRCS
+ pthread_attr_destroy.cpp
+ HDRS
+ pthread_attr_destroy.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_getdetachstate
+ SRCS
+ pthread_attr_getdetachstate.cpp
+ HDRS
+ pthread_attr_getdetachstate.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_setdetachstate
+ SRCS
+ pthread_attr_setdetachstate.cpp
+ HDRS
+ pthread_attr_setdetachstate.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_getguardsize
+ SRCS
+ pthread_attr_getguardsize.cpp
+ HDRS
+ pthread_attr_getguardsize.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_setguardsize
+ SRCS
+ pthread_attr_setguardsize.cpp
+ HDRS
+ pthread_attr_setguardsize.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_getstacksize
+ SRCS
+ pthread_attr_getstacksize.cpp
+ HDRS
+ pthread_attr_getstacksize.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_setstacksize
+ SRCS
+ pthread_attr_setstacksize.cpp
+ HDRS
+ pthread_attr_setstacksize.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_getstack
+ SRCS
+ pthread_attr_getstack.cpp
+ HDRS
+ pthread_attr_getstack.h
+ DEPENDS
+ libc.include.pthread
+)
+
+add_entrypoint_object(
+ pthread_attr_setstack
+ SRCS
+ pthread_attr_setstack.cpp
+ HDRS
+ pthread_attr_setstack.h
+ DEPENDS
+ libc.include.pthread
+)
+
add_header_library(
pthread_mutexattr
HDRS
diff --git a/libc/src/pthread/pthread_attr_destroy.cpp b/libc/src/pthread/pthread_attr_destroy.cpp
new file mode 100644
index 000000000000..592d002483d8
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_destroy.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of the pthread_attr_destroy ------------------------===//
+//
+// 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_attr_destroy.h"
+
+#include "src/__support/common.h"
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_destroy, (pthread_attr_t * attr)) {
+ // There is nothing to cleanup.
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_destroy.h b/libc/src/pthread/pthread_attr_destroy.h
new file mode 100644
index 000000000000..5d01bc8d782d
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_destroy.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_attr_destroy ----------*- 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_ATTR_DESTROY_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_DESTROY_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_destroy(pthread_attr_t *attr);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_DESTROY_H
diff --git a/libc/src/pthread/pthread_attr_getdetachstate.cpp b/libc/src/pthread/pthread_attr_getdetachstate.cpp
new file mode 100644
index 000000000000..18f4637e1c8f
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_getdetachstate.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of the pthread_attr_getdetachstate -----------------===//
+//
+// 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_attr_getdetachstate.h"
+
+#include "src/__support/common.h"
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_getdetachstate,
+ (const pthread_attr_t *attr, int *detachstate)) {
+ *detachstate = attr->__detachstate;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_getdetachstate.h b/libc/src/pthread/pthread_attr_getdetachstate.h
new file mode 100644
index 000000000000..fd5ee886daeb
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_getdetachstate.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_attr_getdetachstate ---*- 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_ATTR_GETDETACHSTATE_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_GETDETACHSTATE_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detach_state);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_GETDETACHSTATE_H
diff --git a/libc/src/pthread/pthread_attr_getguardsize.cpp b/libc/src/pthread/pthread_attr_getguardsize.cpp
new file mode 100644
index 000000000000..79d80feed713
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_getguardsize.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of the pthread_attr_getguardsize -----------------===//
+//
+// 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_attr_getguardsize.h"
+
+#include "src/__support/common.h"
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_getguardsize,
+ (const pthread_attr_t *__restrict attr,
+ size_t *__restrict guardsize)) {
+ *guardsize = attr->__guardsize;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_getguardsize.h b/libc/src/pthread/pthread_attr_getguardsize.h
new file mode 100644
index 000000000000..61072b9350fe
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_getguardsize.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for pthread_attr_getguardsize -----*- 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_ATTR_GETGUARDSIZE_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_GETGUARDSIZE_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_getguardsize(const pthread_attr_t *__restrict attr,
+ size_t *__restrict guardsize);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_GETGUARDSIZE_H
diff --git a/libc/src/pthread/pthread_attr_getstack.cpp b/libc/src/pthread/pthread_attr_getstack.cpp
new file mode 100644
index 000000000000..fea940489e6f
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_getstack.cpp
@@ -0,0 +1,25 @@
+//===-- Implementation of the pthread_attr_getstack -----------------===//
+//
+// 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_attr_getstack.h"
+
+#include "src/__support/common.h"
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_getstack,
+ (const pthread_attr_t *__restrict attr,
+ void **__restrict stack, size_t *__restrict stacksize)) {
+ *stack = attr->__stack;
+ *stacksize = attr->__stacksize;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_getstack.h b/libc/src/pthread/pthread_attr_getstack.h
new file mode 100644
index 000000000000..d0164738349b
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_getstack.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for pthread_attr_getstack ---------*- 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_ATTR_GETSTACK_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_GETSTACK_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_getstack(const pthread_attr_t *__restrict attr,
+ void **__restrict stack,
+ size_t *__restrict stacksize);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_GETSTACK_H
diff --git a/libc/src/pthread/pthread_attr_getstacksize.cpp b/libc/src/pthread/pthread_attr_getstacksize.cpp
new file mode 100644
index 000000000000..2b33d6fc8a44
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_getstacksize.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of the pthread_attr_getstacksize -----------------===//
+//
+// 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_attr_getstacksize.h"
+
+#include "src/__support/common.h"
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_getstacksize,
+ (const pthread_attr_t *__restrict attr,
+ size_t *__restrict stacksize)) {
+ *stacksize = attr->__stacksize;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_getstacksize.h b/libc/src/pthread/pthread_attr_getstacksize.h
new file mode 100644
index 000000000000..cb27a5e1927e
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_getstacksize.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for pthread_attr_getstacksize -----*- 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_ATTR_GETSTACKSIZE_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_GETSTACKSIZE_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_getstacksize(const pthread_attr_t *__restrict attr,
+ size_t *__restrict stacksize);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_GETSTACKSIZE_H
diff --git a/libc/src/pthread/pthread_attr_init.cpp b/libc/src/pthread/pthread_attr_init.cpp
new file mode 100644
index 000000000000..84b352022874
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_init.cpp
@@ -0,0 +1,28 @@
+//===-- Implementation of the pthread_attr_init ---------------------------===//
+//
+// 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_attr_init.h"
+
+#include "src/__support/common.h"
+
+#include <linux/param.h> // For EXEC_PAGESIZE.
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_init, (pthread_attr_t * attr)) {
+ *attr = pthread_attr_t{
+ false, // Not detached
+ nullptr, // Let the thread manage its stack
+ 1 << 16, // 64KB stack size
+ EXEC_PAGESIZE, // Default page size for the guard size.
+ };
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_init.h b/libc/src/pthread/pthread_attr_init.h
new file mode 100644
index 000000000000..609e65381db7
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_init.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_attr_init -------------*- 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_ATTR_INIT_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_INIT_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_init(pthread_attr_t *attr);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_INIT_H
diff --git a/libc/src/pthread/pthread_attr_setdetachstate.cpp b/libc/src/pthread/pthread_attr_setdetachstate.cpp
new file mode 100644
index 000000000000..e136538e054f
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_setdetachstate.cpp
@@ -0,0 +1,27 @@
+//===-- Implementation of the pthread_attr_setdetachstate -----------------===//
+//
+// 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_attr_setdetachstate.h"
+
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_setdetachstate,
+ (pthread_attr_t * attr, int detachstate)) {
+ if (detachstate != PTHREAD_CREATE_DETACHED &&
+ detachstate != PTHREAD_CREATE_JOINABLE)
+ return EINVAL;
+ attr->__detachstate = detachstate;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_setdetachstate.h b/libc/src/pthread/pthread_attr_setdetachstate.h
new file mode 100644
index 000000000000..a8f586619f53
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_setdetachstate.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_attr_setdetachstate ---*- 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_ATTR_SETDETACHSTATE_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_SETDETACHSTATE_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_setdetachstate(pthread_attr_t *attr, int detach_state);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_SETDETACHSTATE_H
diff --git a/libc/src/pthread/pthread_attr_setguardsize.cpp b/libc/src/pthread/pthread_attr_setguardsize.cpp
new file mode 100644
index 000000000000..dd2584a55292
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_setguardsize.cpp
@@ -0,0 +1,27 @@
+//===-- Implementation of the pthread_attr_setguardsize -----------------===//
+//
+// 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_attr_setguardsize.h"
+
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <linux/param.h> // For EXEC_PAGESIZE.
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_setguardsize,
+ (pthread_attr_t *__restrict attr, size_t guardsize)) {
+ if (guardsize % EXEC_PAGESIZE != 0)
+ return EINVAL;
+ attr->__guardsize = guardsize;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_setguardsize.h b/libc/src/pthread/pthread_attr_setguardsize.h
new file mode 100644
index 000000000000..d9e159874f26
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_setguardsize.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_attr_setguardsize -----*- 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_ATTR_SETGUARDSIZE_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_SETGUARDSIZE_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_SETGUARDSIZE_H
diff --git a/libc/src/pthread/pthread_attr_setstack.cpp b/libc/src/pthread/pthread_attr_setstack.cpp
new file mode 100644
index 000000000000..60a7a40326ef
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_setstack.cpp
@@ -0,0 +1,33 @@
+//===-- Implementation of the pthread_attr_setstack -----------------===//
+//
+// 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_attr_setstack.h"
+
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <linux/param.h> // For EXEC_PAGESIZE.
+#include <pthread.h>
+#include <stdint.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_setstack,
+ (pthread_attr_t *__restrict attr, void *stack,
+ size_t stacksize)) {
+ if (stacksize < PTHREAD_STACK_MIN)
+ return EINVAL;
+ uintptr_t stackaddr = reinterpret_cast<uintptr_t>(stack);
+ if ((stackaddr % 16 != 0) || ((stackaddr + stacksize) % 16 != 0))
+ return EINVAL;
+ attr->__stack = stack;
+ attr->__stacksize = stacksize;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_setstack.h b/libc/src/pthread/pthread_attr_setstack.h
new file mode 100644
index 000000000000..44ee2c9e35de
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_setstack.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_attr_setstack ---------*- 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_ATTR_SETSTACK_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_SETSTACK_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_setstack(pthread_attr_t *attr, void *stack, size_t stacksize);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_SETSTACK_H
diff --git a/libc/src/pthread/pthread_attr_setstacksize.cpp b/libc/src/pthread/pthread_attr_setstacksize.cpp
new file mode 100644
index 000000000000..adf568db46fa
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_setstacksize.cpp
@@ -0,0 +1,28 @@
+//===-- Implementation of the pthread_attr_setstacksize -----------------===//
+//
+// 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_attr_setstacksize.h"
+
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <linux/param.h> // For EXEC_PAGESIZE.
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, pthread_attr_setstacksize,
+ (pthread_attr_t *__restrict attr, size_t stacksize)) {
+ if (stacksize < PTHREAD_STACK_MIN)
+ return EINVAL;
+ attr->__stack = nullptr;
+ attr->__stacksize = stacksize;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/pthread/pthread_attr_setstacksize.h b/libc/src/pthread/pthread_attr_setstacksize.h
new file mode 100644
index 000000000000..40ee5c07d44e
--- /dev/null
+++ b/libc/src/pthread/pthread_attr_setstacksize.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for pthread_attr_setstacksize -----*- 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_ATTR_SETSTACKSIZE_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_SETSTACKSIZE_H
+
+#include <pthread.h>
+
+namespace __llvm_libc {
+
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_ATTR_SETSTACKSIZE_H
diff --git a/libc/test/src/pthread/CMakeLists.txt b/libc/test/src/pthread/CMakeLists.txt
index 552c7feca2d6..db0516cecc4f 100644
--- a/libc/test/src/pthread/CMakeLists.txt
+++ b/libc/test/src/pthread/CMakeLists.txt
@@ -1,6 +1,27 @@
add_libc_testsuite(libc_pthread_unittests)
add_libc_unittest(
+ pthread_attr_test
+ SUITE
+ libc_pthread_unittests
+ SRCS
+ pthread_attr_test.cpp
+ DEPENDS
+ libc.include.errno
+ libc.include.pthread
+ libc.src.pthread.pthread_attr_destroy
+ libc.src.pthread.pthread_attr_init
+ libc.src.pthread.pthread_attr_getdetachstate
+ libc.src.pthread.pthread_attr_getguardsize
+ libc.src.pthread.pthread_attr_getstacksize
+ libc.src.pthread.pthread_attr_getstack
+ libc.src.pthread.pthread_attr_setdetachstate
+ libc.src.pthread.pthread_attr_setguardsize
+ libc.src.pthread.pthread_attr_setstacksize
+ libc.src.pthread.pthread_attr_setstack
+)
+
+add_libc_unittest(
pthread_mutexattr_test
SUITE
libc_pthread_unittests
diff --git a/libc/test/src/pthread/pthread_attr_test.cpp b/libc/test/src/pthread/pthread_attr_test.cpp
new file mode 100644
index 000000000000..fe002db966dc
--- /dev/null
+++ b/libc/test/src/pthread/pthread_attr_test.cpp
@@ -0,0 +1,113 @@
+//===-- Unittests for pthread_attr_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_attr_destroy.h"
+#include "src/pthread/pthread_attr_getdetachstate.h"
+#include "src/pthread/pthread_attr_getguardsize.h"
+#include "src/pthread/pthread_attr_getstack.h"
+#include "src/pthread/pthread_attr_getstacksize.h"
+#include "src/pthread/pthread_attr_init.h"
+#include "src/pthread/pthread_attr_setdetachstate.h"
+#include "src/pthread/pthread_attr_setguardsize.h"
+#include "src/pthread/pthread_attr_setstack.h"
+#include "src/pthread/pthread_attr_setstacksize.h"
+
+#include "utils/UnitTest/Test.h"
+
+#include <errno.h>
+#include <linux/param.h> // For EXEC_PAGESIZE.
+#include <pthread.h>
+
+TEST(LlvmLibcPThreadAttrTest, InitAndDestroy) {
+ pthread_attr_t attr;
+ ASSERT_EQ(__llvm_libc::pthread_attr_init(&attr), 0);
+
+ int detachstate;
+ ASSERT_EQ(__llvm_libc::pthread_attr_getdetachstate(&attr, &detachstate), 0);
+ ASSERT_EQ(detachstate, int(PTHREAD_CREATE_JOINABLE));
+
+ size_t guardsize;
+ ASSERT_EQ(__llvm_libc::pthread_attr_getguardsize(&attr, &guardsize), 0);
+ ASSERT_EQ(guardsize, size_t(EXEC_PAGESIZE));
+
+ ASSERT_EQ(__llvm_libc::pthread_attr_destroy(&attr), 0);
+}
+
+TEST(LlvmLibcPThreadattrTest, SetAndGetDetachState) {
+ pthread_attr_t attr;
+ ASSERT_EQ(__llvm_libc::pthread_attr_init(&attr), 0);
+
+ int detachstate;
+ __llvm_libc::pthread_attr_getdetachstate(&attr, &detachstate);
+ ASSERT_EQ(detachstate, int(PTHREAD_CREATE_JOINABLE));
+ ASSERT_EQ(
+ __llvm_libc::pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED),
+ 0);
+ ASSERT_EQ(__llvm_libc::pthread_attr_getdetachstate(&attr, &detachstate), 0);
+ ASSERT_EQ(detachstate, int(PTHREAD_CREATE_DETACHED));
+
+ ASSERT_EQ(__llvm_libc::pthread_attr_setdetachstate(&attr, 0xBAD), EINVAL);
+
+ ASSERT_EQ(__llvm_libc::pthread_attr_destroy(&attr), 0);
+}
+
+TEST(LlvmLibcPThreadattrTest, SetAndGetGuardSize) {
+ pthread_attr_t attr;
+ ASSERT_EQ(__llvm_libc::pthread_attr_init(&attr), 0);
+
+ size_t guardsize;
+ ASSERT_EQ(__llvm_libc::pthread_attr_getguardsize(&attr, &guardsize), 0);
+ ASSERT_EQ(guardsize, size_t(EXEC_PAGESIZE));
+ ASSERT_EQ(__llvm_libc::pthread_attr_setguardsize(&attr, 2 * EXEC_PAGESIZE),
+ 0);
+ ASSERT_EQ(__llvm_libc::pthread_attr_getguardsize(&attr, &guardsize), 0);
+ ASSERT_EQ(guardsize, size_t(2 * EXEC_PAGESIZE));
+
+ ASSERT_EQ(__llvm_libc::pthread_attr_setguardsize(&attr, EXEC_PAGESIZE / 2),
+ EINVAL);
+
+ ASSERT_EQ(__llvm_libc::pthread_attr_destroy(&attr), 0);
+}
+
+TEST(LlvmLibcPThreadattrTest, SetAndGetStackSize) {
+ pthread_attr_t attr;
+ ASSERT_EQ(__llvm_libc::pthread_attr_init(&attr), 0);
+
+ size_t stacksize;
+ ASSERT_EQ(
+ __llvm_libc::pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN << 2), 0);
+ ASSERT_EQ(__llvm_libc::pthread_attr_getstacksize(&attr, &stacksize), 0);
+ ASSERT_EQ(stacksize, size_t(PTHREAD_STACK_MIN << 2));
+
+ ASSERT_EQ(
+ __llvm_libc::pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN / 2),
+ EINVAL);
+
+ ASSERT_EQ(__llvm_libc::pthread_attr_destroy(&attr), 0);
+}
+
+TEST(LlvmLibcPThreadattrTest, SetAndGetStack) {
+ pthread_attr_t attr;
+ ASSERT_EQ(__llvm_libc::pthread_attr_init(&attr), 0);
+
+ void *stack;
+ size_t stacksize;
+ ASSERT_EQ(
+ __llvm_libc::pthread_attr_setstack(&attr, 0, PTHREAD_STACK_MIN << 2), 0);
+ ASSERT_EQ(__llvm_libc::pthread_attr_getstack(&attr, &stack, &stacksize), 0);
+ ASSERT_EQ(stacksize, size_t(PTHREAD_STACK_MIN << 2));
+ ASSERT_EQ(reinterpret_cast<uintptr_t>(stack), uintptr_t(0));
+
+ ASSERT_EQ(__llvm_libc::pthread_attr_setstack(
+ &attr, reinterpret_cast<void *>(1), PTHREAD_STACK_MIN << 2),
+ EINVAL);
+ ASSERT_EQ(__llvm_libc::pthread_attr_setstack(&attr, 0, PTHREAD_STACK_MIN / 2),
+ EINVAL);
+
+ ASSERT_EQ(__llvm_libc::pthread_attr_destroy(&attr), 0);
+}