diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -230,6 +230,16 @@ 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 --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -238,7 +238,10 @@ } 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 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -223,6 +223,17 @@ # 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 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -161,6 +161,7 @@ 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 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -18,6 +18,7 @@ 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 --- /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 + +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 --- 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 --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -20,6 +20,13 @@ NamedType ModeTType = NamedType<"mode_t">; NamedType OffTType = NamedType<"off_t">; NamedType SSizeTType = NamedType<"ssize_t">; + + NamedType PThreadAttrTType = NamedType<"pthread_attr_t">; + PtrType PThreadAttrTPtr = PtrType; + RestrictedPtrType RestrictedPThreadAttrTPtr = RestrictedPtrType; + ConstType ConstPThreadAttrTPtr = ConstType; + ConstType ConstRestrictedPThreadAttrTPtr = ConstType; + NamedType PThreadMutexAttrTType = NamedType<"pthread_mutexattr_t">; PtrType PThreadMutexAttrTPtr = PtrType; RestrictedPtrType RestrictedPThreadMutexAttrTPtr = RestrictedPtrType; @@ -379,9 +386,59 @@ HeaderSpec PThread = HeaderSpec< "pthread.h", [], // Macros - [PThreadMutexAttrTType], // Types + [PThreadAttrTType, PThreadMutexAttrTType], // Types [], // Enumerations [ + FunctionSpec< + "pthread_attr_init", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "pthread_attr_destroy", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "pthread_attr_getdetachstate", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_attr_setdetachstate", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_attr_getguardsize", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_attr_setguardsize", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_attr_getstacksize", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_attr_setstacksize", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_attr_getstack", + RetValSpec, + [ArgSpec, ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_attr_setstack", + RetValSpec, + [ArgSpec, ArgSpec, ArgSpec] + >, FunctionSpec< "pthread_mutexattr_init", RetValSpec, diff --git a/libc/spec/spec.td b/libc/spec/spec.td --- a/libc/spec/spec.td +++ b/libc/spec/spec.td @@ -50,8 +50,14 @@ // Common types def VoidPtr : PtrType; +def VoidPtrPtr : PtrType; +def RestrictedVoidPtrPtr : RestrictedPtrType; def ConstVoidPtr : ConstType; + def SizeTType : NamedType<"size_t">; +def SizeTPtr : PtrType; +def RestrictedSizeTPtr : RestrictedPtrType; + def LongDoublePtr : PtrType; def IntMaxTType : NamedType<"intmax_t">; diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt --- 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.h b/libc/src/pthread/pthread_attr_destroy.h new file mode 100644 --- /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 + +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_destroy.cpp b/libc/src/pthread/pthread_attr_destroy.cpp new file mode 100644 --- /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 + +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_getdetachstate.h b/libc/src/pthread/pthread_attr_getdetachstate.h new file mode 100644 --- /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 + +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_getdetachstate.cpp b/libc/src/pthread/pthread_attr_getdetachstate.cpp new file mode 100644 --- /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 + +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_getguardsize.h b/libc/src/pthread/pthread_attr_getguardsize.h new file mode 100644 --- /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 + +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_getguardsize.cpp b/libc/src/pthread/pthread_attr_getguardsize.cpp new file mode 100644 --- /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 + +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_getstack.h b/libc/src/pthread/pthread_attr_getstack.h new file mode 100644 --- /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 + +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_getstack.cpp b/libc/src/pthread/pthread_attr_getstack.cpp new file mode 100644 --- /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 + +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_getstacksize.h b/libc/src/pthread/pthread_attr_getstacksize.h new file mode 100644 --- /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 + +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_getstacksize.cpp b/libc/src/pthread/pthread_attr_getstacksize.cpp new file mode 100644 --- /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 + +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_init.h b/libc/src/pthread/pthread_attr_init.h new file mode 100644 --- /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 + +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_init.cpp b/libc/src/pthread/pthread_attr_init.cpp new file mode 100644 --- /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 // For EXEC_PAGESIZE. +#include + +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_setdetachstate.h b/libc/src/pthread/pthread_attr_setdetachstate.h new file mode 100644 --- /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 + +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_setdetachstate.cpp b/libc/src/pthread/pthread_attr_setdetachstate.cpp new file mode 100644 --- /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 +#include + +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_setguardsize.h b/libc/src/pthread/pthread_attr_setguardsize.h new file mode 100644 --- /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 + +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_setguardsize.cpp b/libc/src/pthread/pthread_attr_setguardsize.cpp new file mode 100644 --- /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 +#include // For EXEC_PAGESIZE. +#include + +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_setstack.h b/libc/src/pthread/pthread_attr_setstack.h new file mode 100644 --- /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 + +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_setstack.cpp b/libc/src/pthread/pthread_attr_setstack.cpp new file mode 100644 --- /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 +#include // For EXEC_PAGESIZE. +#include +#include + +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(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_setstacksize.h b/libc/src/pthread/pthread_attr_setstacksize.h new file mode 100644 --- /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 + +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/src/pthread/pthread_attr_setstacksize.cpp b/libc/src/pthread/pthread_attr_setstacksize.cpp new file mode 100644 --- /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 +#include // For EXEC_PAGESIZE. +#include + +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/test/src/pthread/CMakeLists.txt b/libc/test/src/pthread/CMakeLists.txt --- a/libc/test/src/pthread/CMakeLists.txt +++ b/libc/test/src/pthread/CMakeLists.txt @@ -1,5 +1,26 @@ 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 diff --git a/libc/test/src/pthread/pthread_attr_test.cpp b/libc/test/src/pthread/pthread_attr_test.cpp new file mode 100644 --- /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 +#include // For EXEC_PAGESIZE. +#include + +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(stack), uintptr_t(0)); + + ASSERT_EQ(__llvm_libc::pthread_attr_setstack( + &attr, reinterpret_cast(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); +}