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 @@ -228,6 +228,16 @@ libc.src.threads.mtx_unlock libc.src.threads.thrd_create libc.src.threads.thrd_join + + # pthread.h entrypoints + libc.src.pthread.pthread_mutexattr_destroy + libc.src.pthread.pthread_mutexattr_init + libc.src.pthread.pthread_mutexattr_getpshared + libc.src.pthread.pthread_mutexattr_getrobust + libc.src.pthread.pthread_mutexattr_gettype + libc.src.pthread.pthread_mutexattr_setpshared + libc.src.pthread.pthread_mutexattr_setrobust + libc.src.pthread.pthread_mutexattr_settype ) endif() 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 @@ -237,6 +237,10 @@ ]; } +def PThreadAPI : PublicAPI<"pthread.h"> { + let Types = ["pthread_mutexattr_t"]; +} + def UniStdAPI : PublicAPI<"unistd.h"> { let Types = ["off_t", "size_t", "ssize_t"]; } 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 @@ -222,6 +222,16 @@ # assert.h entrypoints # libc.src.assert.__assert_fail + # pthread.h entrypoints + libc.src.pthread.pthread_mutexattr_destroy + libc.src.pthread.pthread_mutexattr_init + libc.src.pthread.pthread_mutexattr_getpshared + libc.src.pthread.pthread_mutexattr_getrobust + libc.src.pthread.pthread_mutexattr_gettype + libc.src.pthread.pthread_mutexattr_setpshared + libc.src.pthread.pthread_mutexattr_setrobust + libc.src.pthread.pthread_mutexattr_settype + # stdlib.h entrypoints libc.src.stdlib._Exit # libc.src.stdlib.abort diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -155,6 +155,15 @@ .llvm-libc-types.ssize_t ) +add_gen_header( + pthread + DEF_FILE pthread.h.def + GEN_HDR pthread.h + DEPENDS + .llvm_libc_common_h + .llvm-libc-types.pthread_mutexattr_t +) + # TODO: Not all platforms will have a include/sys directory. Add the sys # directory and the targets for sys/*.h files conditional to the OS requiring # them. 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_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) diff --git a/libc/include/llvm-libc-types/pthread_mutexattr_t.h b/libc/include/llvm-libc-types/pthread_mutexattr_t.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/pthread_mutexattr_t.h @@ -0,0 +1,16 @@ +//===-- Definition of pthread_mutexattr_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_MUTEXATTR_T_H +#define __LLVM_LIBC_TYPES_PTHREAD_MUTEXATTR_T_H + +// pthread_mutexattr_t is a collection bit mapped flags. The mapping is internal +// detail of the libc implementation. +typedef unsigned int pthread_mutexattr_t; + +#endif // __LLVM_LIBC_TYPES_PTHREAD_MUTEXATTR_T_H diff --git a/libc/include/pthread.h.def b/libc/include/pthread.h.def new file mode 100644 --- /dev/null +++ b/libc/include/pthread.h.def @@ -0,0 +1,29 @@ +//===-- POSIX header pthread.h --------------------------------------------===// +// +// 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_PTHREAD_H +#define LLVM_LIBC_PTHREAD_H + +#include <__llvm-libc-common.h> + +enum { + PTHREAD_MUTEX_NORMAL = 0x0, + PTHREAD_MUTEX_ERRORCHECK = 0x1, + PTHREAD_MUTEX_RECURSIVE = 0x2, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL, + + PTHREAD_PROCESS_PRIVATE = 0x0, + PTHREAD_PROCESS_SHARED = 0x1, + + PTHREAD_MUTEX_STALLED = 0x0, + PTHREAD_MUTEX_ROBUST = 0x1, +}; + +%%public_api() + +#endif // LLVM_LIBC_PTHREAD_H 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,11 @@ NamedType ModeTType = NamedType<"mode_t">; NamedType OffTType = NamedType<"off_t">; NamedType SSizeTType = NamedType<"ssize_t">; + NamedType PThreadMutexAttrTType = NamedType<"pthread_mutexattr_t">; + PtrType PThreadMutexAttrTPtr = PtrType; + RestrictedPtrType RestrictedPThreadMutexAttrTPtr = RestrictedPtrType; + ConstType ConstPThreadMutexAttrTPtr = ConstType; + ConstType ConstRestrictedPThreadMutexAttrTPtr = ConstType; HeaderSpec Errno = HeaderSpec< "errno.h", @@ -371,10 +376,80 @@ ] >; + HeaderSpec PThread = HeaderSpec< + "pthread.h", + [], // Macros + [PThreadMutexAttrTType], // Types + [], // Enumerations + [ + FunctionSpec< + "pthread_mutexattr_init", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_destroy", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_gettype", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_settype", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_getrobust", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_setrobust", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_getpshared", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_setpshared", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_getprotocol", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_setprotocol", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_getprioceiling", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "pthread_mutexattr_setprioceiling", + RetValSpec, + [ArgSpec, ArgSpec] + >, + ] + >; + let Headers = [ CType, Errno, FCntl, + PThread, Signal, StdLib, SysMMan, diff --git a/libc/spec/spec.td b/libc/spec/spec.td --- a/libc/spec/spec.td +++ b/libc/spec/spec.td @@ -84,6 +84,7 @@ def ThrdTTypePtr : PtrType; def IntPtr : PtrType; +def RestrictedIntPtr : RestrictedPtrType; def FloatPtr : PtrType; def DoublePtr : PtrType; diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt --- a/libc/src/CMakeLists.txt +++ b/libc/src/CMakeLists.txt @@ -10,6 +10,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux") add_subdirectory(fcntl) + add_subdirectory(pthread) add_subdirectory(sys) add_subdirectory(unistd) endif() diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/pthread/CMakeLists.txt @@ -0,0 +1,98 @@ +add_header_library( + pthread_mutexattr + HDRS + pthread_mutexattr.h + DEPENDS + libc.include.pthread +) + +add_entrypoint_object( + pthread_mutexattr_init + SRCS + pthread_mutexattr_init.cpp + HDRS + pthread_mutexattr_init.h + DEPENDS + .pthread_mutexattr + libc.include.pthread +) + +add_entrypoint_object( + pthread_mutexattr_gettype + SRCS + pthread_mutexattr_gettype.cpp + HDRS + pthread_mutexattr_gettype.h + DEPENDS + .pthread_mutexattr + libc.include.pthread +) + +add_entrypoint_object( + pthread_mutexattr_settype + SRCS + pthread_mutexattr_settype.cpp + HDRS + pthread_mutexattr_settype.h + DEPENDS + .pthread_mutexattr + libc.include.pthread +) + +add_entrypoint_object( + pthread_mutexattr_destroy + SRCS + pthread_mutexattr_destroy.cpp + HDRS + pthread_mutexattr_destroy.h + DEPENDS + .pthread_mutexattr + libc.include.errno + libc.include.pthread +) + +add_entrypoint_object( + pthread_mutexattr_getrobust + SRCS + pthread_mutexattr_getrobust.cpp + HDRS + pthread_mutexattr_getrobust.h + DEPENDS + .pthread_mutexattr + libc.include.pthread +) + +add_entrypoint_object( + pthread_mutexattr_setrobust + SRCS + pthread_mutexattr_setrobust.cpp + HDRS + pthread_mutexattr_setrobust.h + DEPENDS + .pthread_mutexattr + libc.include.errno + libc.include.pthread +) + +add_entrypoint_object( + pthread_mutexattr_getpshared + SRCS + pthread_mutexattr_getpshared.cpp + HDRS + pthread_mutexattr_getpshared.h + DEPENDS + .pthread_mutexattr + libc.include.pthread +) + +add_entrypoint_object( + pthread_mutexattr_setpshared + SRCS + pthread_mutexattr_setpshared.cpp + HDRS + pthread_mutexattr_setpshared.h + DEPENDS + .pthread_mutexattr + libc.include.errno + libc.include.pthread +) diff --git a/libc/src/pthread/pthread_mutexattr.h b/libc/src/pthread/pthread_mutexattr.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr.h @@ -0,0 +1,36 @@ +//===-- Declarations related mutex attribute objects -----------*- 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_MUTEXATTR_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_H + +#include + +namespace __llvm_libc { + +enum class PThreadMutexAttrPos : unsigned int { + TYPE_SHIFT = 0, + TYPE_MASK = 0x3 << TYPE_SHIFT, // Type is encoded in 2 bits + + ROBUST_SHIFT = 2, + ROBUST_MASK = 0x1 << ROBUST_SHIFT, + + PSHARED_SHIFT = 3, + PSHARED_MASK = 0x1 << PSHARED_SHIFT, + + // TODO: Add a mask for protocol and prioceiling when it is supported. +}; + +constexpr pthread_mutexattr_t DEFAULT_MUTEXATTR = + PTHREAD_MUTEX_DEFAULT << unsigned(PThreadMutexAttrPos::TYPE_SHIFT) | + PTHREAD_MUTEX_STALLED << unsigned(PThreadMutexAttrPos::ROBUST_SHIFT) | + PTHREAD_PROCESS_PRIVATE << unsigned(PThreadMutexAttrPos::PSHARED_SHIFT); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_H diff --git a/libc/src/pthread/pthread_mutexattr_destroy.h b/libc/src/pthread/pthread_mutexattr_destroy.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_destroy.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_mutexattr_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_MUTEXATTR_DESTROY_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_DESTROY_H + +#include + +namespace __llvm_libc { + +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_DESTROY_H diff --git a/libc/src/pthread/pthread_mutexattr_destroy.cpp b/libc/src/pthread/pthread_mutexattr_destroy.cpp new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_destroy.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of the pthread_mutexattr_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_mutexattr_destroy.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, pthread_mutexattr_destroy, + (pthread_mutexattr_t * attr)) { + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/pthread/pthread_mutexattr_getpshared.h b/libc/src/pthread/pthread_mutexattr_getpshared.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_getpshared.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_mutexattr_getpshared --*- 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_MUTEXATTR_GETPSHARED_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_GETPSHARED_H + +#include + +namespace __llvm_libc { + +int pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict attr, + int *__restrict pshared); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_GETPSHARED_H diff --git a/libc/src/pthread/pthread_mutexattr_getpshared.cpp b/libc/src/pthread/pthread_mutexattr_getpshared.cpp new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_getpshared.cpp @@ -0,0 +1,26 @@ +//===-- Implementation of the pthread_mutexattr_getpshared ----------------===// +// +// 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_mutexattr_getpshared.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, pthread_mutexattr_getpshared, + (const pthread_mutexattr_t *__restrict attr, + int *__restrict pshared)) { + *pshared = (*attr & unsigned(PThreadMutexAttrPos::PSHARED_MASK)) >> + unsigned(PThreadMutexAttrPos::PSHARED_SHIFT); + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/pthread/pthread_mutexattr_getrobust.h b/libc/src/pthread/pthread_mutexattr_getrobust.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_getrobust.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_mutexattr_getrobust ---*- 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_MUTEXATTR_GETROBUST_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_GETROBUST_H + +#include + +namespace __llvm_libc { + +int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__restrict attr, + int *__restrict robust); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_GETROBUST_H diff --git a/libc/src/pthread/pthread_mutexattr_getrobust.cpp b/libc/src/pthread/pthread_mutexattr_getrobust.cpp new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_getrobust.cpp @@ -0,0 +1,26 @@ +//===-- Implementation of the pthread_mutexattr_getrobust -----------------===// +// +// 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_mutexattr_getrobust.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, pthread_mutexattr_getrobust, + (const pthread_mutexattr_t *__restrict attr, + int *__restrict robust)) { + *robust = (*attr & unsigned(PThreadMutexAttrPos::ROBUST_MASK)) >> + unsigned(PThreadMutexAttrPos::ROBUST_SHIFT); + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/pthread/pthread_mutexattr_gettype.h b/libc/src/pthread/pthread_mutexattr_gettype.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_gettype.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_mutexattr_gettype -----*- 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_MUTEXATTR_GETTYPE_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_GETTYPE_H + +#include + +namespace __llvm_libc { + +int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict attr, + int *__restrict type); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_GETTYPE_H diff --git a/libc/src/pthread/pthread_mutexattr_gettype.cpp b/libc/src/pthread/pthread_mutexattr_gettype.cpp new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_gettype.cpp @@ -0,0 +1,26 @@ +//===-- Implementation of the pthread_mutexattr_gettype -------------------===// +// +// 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_mutexattr_gettype.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, pthread_mutexattr_gettype, + (const pthread_mutexattr_t *__restrict attr, + int *__restrict type)) { + *type = (*attr & unsigned(PThreadMutexAttrPos::TYPE_MASK)) >> + unsigned(PThreadMutexAttrPos::TYPE_SHIFT); + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/pthread/pthread_mutexattr_init.h b/libc/src/pthread/pthread_mutexattr_init.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_init.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_mutexattr_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_MUTEXATTR_INIT_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_INIT_H + +#include + +namespace __llvm_libc { + +int pthread_mutexattr_init(pthread_mutexattr_t *attr); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_INIT_H diff --git a/libc/src/pthread/pthread_mutexattr_init.cpp b/libc/src/pthread/pthread_mutexattr_init.cpp new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_init.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of the pthread_mutexattr_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_mutexattr_init.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, pthread_mutexattr_init, (pthread_mutexattr_t * attr)) { + // Set the default attributes and mark the attribute object as initiliazed + // by setting the first bit. + *attr = DEFAULT_MUTEXATTR; + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/pthread/pthread_mutexattr_setpshared.h b/libc/src/pthread/pthread_mutexattr_setpshared.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_setpshared.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_mutexattr_setpshared --*- 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_MUTEXATTR_SETpshared_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_SETpshared_H + +#include + +namespace __llvm_libc { + +int pthread_mutexattr_setpshared(pthread_mutexattr_t *__restrict attr, + int pshared); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_SETpshared_H diff --git a/libc/src/pthread/pthread_mutexattr_setpshared.cpp b/libc/src/pthread/pthread_mutexattr_setpshared.cpp new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_setpshared.cpp @@ -0,0 +1,29 @@ +//===-- Implementation of the pthread_mutexattr_setpshared ----------------===// +// +// 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_mutexattr_setpshared.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" + +#include +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, pthread_mutexattr_setpshared, + (pthread_mutexattr_t *__restrict attr, int pshared)) { + if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) + return EINVAL; + pthread_mutexattr_t old = *attr; + old &= ~unsigned(PThreadMutexAttrPos::PSHARED_MASK); + *attr = old | (pshared << unsigned(PThreadMutexAttrPos::PSHARED_SHIFT)); + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/pthread/pthread_mutexattr_setrobust.h b/libc/src/pthread/pthread_mutexattr_setrobust.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_setrobust.h @@ -0,0 +1,21 @@ +//===-- Implementation header for pthread_mutexattr_setrobust ---*- 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_MUTEXATTR_SETROBUST_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_SETROBUST_H + +#include + +namespace __llvm_libc { + +int pthread_mutexattr_setrobust(pthread_mutexattr_t *__restrict attr, + int robust); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_SETROBUST_H diff --git a/libc/src/pthread/pthread_mutexattr_setrobust.cpp b/libc/src/pthread/pthread_mutexattr_setrobust.cpp new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_setrobust.cpp @@ -0,0 +1,29 @@ +//===-- Implementation of the pthread_mutexattr_setrobust -----------------===// +// +// 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_mutexattr_setrobust.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" + +#include +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, pthread_mutexattr_setrobust, + (pthread_mutexattr_t *__restrict attr, int robust)) { + if (robust != PTHREAD_MUTEX_STALLED && robust != PTHREAD_MUTEX_ROBUST) + return EINVAL; + pthread_mutexattr_t old = *attr; + old &= ~unsigned(PThreadMutexAttrPos::ROBUST_MASK); + *attr = old | (robust << unsigned(PThreadMutexAttrPos::ROBUST_SHIFT)); + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/pthread/pthread_mutexattr_settype.h b/libc/src/pthread/pthread_mutexattr_settype.h new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_settype.h @@ -0,0 +1,20 @@ +//===-- Implementation header for pthread_mutexattr_settype -----*- 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_MUTEXATTR_SETTYPE_H +#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_SETTYPE_H + +#include + +namespace __llvm_libc { + +int pthread_mutexattr_settype(pthread_mutexattr_t *__restrict attr, int type); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_MUTEXATTR_SETTYPE_H diff --git a/libc/src/pthread/pthread_mutexattr_settype.cpp b/libc/src/pthread/pthread_mutexattr_settype.cpp new file mode 100644 --- /dev/null +++ b/libc/src/pthread/pthread_mutexattr_settype.cpp @@ -0,0 +1,31 @@ +//===-- Implementation of the pthread_mutexattr_settype -------------------===// +// +// 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_mutexattr_settype.h" +#include "pthread_mutexattr.h" + +#include "src/__support/common.h" + +#include +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, pthread_mutexattr_settype, + (pthread_mutexattr_t *__restrict attr, int type)) { + if (type != PTHREAD_MUTEX_NORMAL && type != PTHREAD_MUTEX_ERRORCHECK && + type != PTHREAD_MUTEX_RECURSIVE) { + return EINVAL; + } + pthread_mutexattr_t old = *attr; + old &= ~unsigned(PThreadMutexAttrPos::TYPE_MASK); + *attr = old | (type << unsigned(PThreadMutexAttrPos::TYPE_SHIFT)); + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt --- a/libc/test/src/CMakeLists.txt +++ b/libc/test/src/CMakeLists.txt @@ -52,6 +52,10 @@ add_subdirectory(threads) add_subdirectory(time) +if(${LIBC_TARGET_OS} STREQUAL "linux") + add_subdirectory(pthread) +endif() + set(public_test ${CMAKE_CURRENT_BINARY_DIR}/public_api_test.cpp) set(entrypoints_name_list "") diff --git a/libc/test/src/pthread/CMakeLists.txt b/libc/test/src/pthread/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/test/src/pthread/CMakeLists.txt @@ -0,0 +1,20 @@ +add_libc_testsuite(libc_pthread_unittests) + +add_libc_unittest( + pthread_mutexattr_test + SUITE + libc_pthread_unittests + SRCS + pthread_mutexattr_test.cpp + DEPENDS + libc.include.errno + libc.include.pthread + libc.src.pthread.pthread_mutexattr_destroy + libc.src.pthread.pthread_mutexattr_init + libc.src.pthread.pthread_mutexattr_getpshared + libc.src.pthread.pthread_mutexattr_getrobust + libc.src.pthread.pthread_mutexattr_gettype + libc.src.pthread.pthread_mutexattr_setpshared + libc.src.pthread.pthread_mutexattr_setrobust + libc.src.pthread.pthread_mutexattr_settype +) diff --git a/libc/test/src/pthread/pthread_mutexattr_test.cpp b/libc/test/src/pthread/pthread_mutexattr_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/pthread/pthread_mutexattr_test.cpp @@ -0,0 +1,91 @@ +//===-- Unittests for pthread_mutexattr_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_mutexattr_destroy.h" +#include "src/pthread/pthread_mutexattr_getpshared.h" +#include "src/pthread/pthread_mutexattr_getrobust.h" +#include "src/pthread/pthread_mutexattr_gettype.h" +#include "src/pthread/pthread_mutexattr_init.h" +#include "src/pthread/pthread_mutexattr_setpshared.h" +#include "src/pthread/pthread_mutexattr_setrobust.h" +#include "src/pthread/pthread_mutexattr_settype.h" +#include "utils/UnitTest/Test.h" + +#include +#include + +TEST(LlvmLibcPThreadMutexAttrTest, InitAndDestroy) { + pthread_mutexattr_t attr; + ASSERT_EQ(__llvm_libc::pthread_mutexattr_init(&attr), 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_destroy(&attr), 0); +} + +TEST(LlvmLibcPThreadMutexAttrTest, SetAndGetType) { + int type; + pthread_mutexattr_t attr; + ASSERT_EQ(__llvm_libc::pthread_mutexattr_init(&attr), 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_gettype(&attr, &type), 0); + ASSERT_EQ(type, int(PTHREAD_MUTEX_DEFAULT)); + + ASSERT_EQ( + __llvm_libc::pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE), + 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_gettype(&attr, &type), 0); + ASSERT_EQ(type, int(PTHREAD_MUTEX_RECURSIVE)); + + ASSERT_EQ( + __llvm_libc::pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK), + 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_gettype(&attr, &type), 0); + ASSERT_EQ(type, int(PTHREAD_MUTEX_ERRORCHECK)); + + ASSERT_EQ(__llvm_libc::pthread_mutexattr_settype(&attr, 0xBAD), EINVAL); +} + +TEST(LlvmLibcPThreadMutexAttrTest, SetAndGetRobust) { + int robust; + pthread_mutexattr_t attr; + ASSERT_EQ(__llvm_libc::pthread_mutexattr_init(&attr), 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_getrobust(&attr, &robust), 0); + ASSERT_EQ(robust, int(PTHREAD_MUTEX_STALLED)); + + ASSERT_EQ( + __llvm_libc::pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST), 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_getrobust(&attr, &robust), 0); + ASSERT_EQ(robust, int(PTHREAD_MUTEX_ROBUST)); + + ASSERT_EQ( + __llvm_libc::pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_STALLED), + 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_getrobust(&attr, &robust), 0); + ASSERT_EQ(robust, int(PTHREAD_MUTEX_STALLED)); + + ASSERT_EQ(__llvm_libc::pthread_mutexattr_setrobust(&attr, 0xBAD), EINVAL); +} + +TEST(LlvmLibcPThreadMutexAttrTest, SetAndGetPShared) { + int pshared; + pthread_mutexattr_t attr; + ASSERT_EQ(__llvm_libc::pthread_mutexattr_init(&attr), 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, int(PTHREAD_PROCESS_PRIVATE)); + + ASSERT_EQ( + __llvm_libc::pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED), + 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, int(PTHREAD_PROCESS_SHARED)); + + ASSERT_EQ( + __llvm_libc::pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE), + 0); + ASSERT_EQ(__llvm_libc::pthread_mutexattr_getpshared(&attr, &pshared), 0); + ASSERT_EQ(pshared, int(PTHREAD_PROCESS_PRIVATE)); + + ASSERT_EQ(__llvm_libc::pthread_mutexattr_setpshared(&attr, 0xBAD), EINVAL); +}