-
Notifications
You must be signed in to change notification settings - Fork 16.8k
[libc][semaphore] Add internal unnamed semaphore implementation #190851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| //===-- Definition of sem_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_HDR_TYPES_SEM_T_H | ||
| #define LLVM_LIBC_HDR_TYPES_SEM_T_H | ||
|
|
||
| #ifdef LIBC_FULL_BUILD | ||
|
|
||
| #include "include/llvm-libc-types/sem_t.h" | ||
|
|
||
| #else // Overlay mode | ||
|
|
||
| #error "Cannot overlay sem_t" | ||
|
|
||
| #endif // LLVM_LIBC_FULL_BUILD | ||
|
|
||
| #endif // LLVM_LIBC_HDR_TYPES_SEM_T_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Definition of sem_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_SEM_T_H | ||
| #define LLVM_LIBC_TYPES_SEM_T_H | ||
|
|
||
| #include "__futex_word.h" | ||
|
|
||
| typedef struct { | ||
| __futex_word __value; // current semaphore count | ||
| unsigned int __canary; // used for sanity check | ||
| unsigned char __reserved[8]; // for future usage, total fixed size 16 bytes | ||
| } sem_t; | ||
|
|
||
| #endif // LLVM_LIBC_TYPES_SEM_T_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| header: semaphore.h | ||
| standards: | ||
| - posix | ||
| types: | ||
| - type_name: sem_t | ||
| functions: | ||
| - name: sem_destroy | ||
| return_type: int | ||
| arguments: | ||
Pengxiang-Huang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - type: sem_t * | ||
| - name: sem_getvalue | ||
| return_type: int | ||
| arguments: | ||
| - type: sem_t *__restrict | ||
| - type: int *__restrict | ||
| - name: sem_init | ||
| return_type: int | ||
| arguments: | ||
| - type: sem_t * | ||
| - type: int | ||
| - type: unsigned int | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| add_header_library( | ||
| posix_semaphore | ||
| HDRS | ||
| posix_semaphore.h | ||
| DEPENDS | ||
| libc.hdr.types.sem_t | ||
| libc.src.__support.CPP.atomic | ||
| libc.src.__support.threads.linux.futex_word_type | ||
| ) | ||
|
|
||
| add_entrypoint_object( | ||
| sem_init | ||
| SRCS | ||
| sem_init.cpp | ||
| HDRS | ||
| sem_init.h | ||
| DEPENDS | ||
| .posix_semaphore | ||
| libc.hdr.errno_macros | ||
| libc.hdr.limits_macros | ||
| libc.include.semaphore | ||
| libc.src.errno.errno | ||
| ) | ||
|
|
||
| add_entrypoint_object( | ||
| sem_destroy | ||
| SRCS | ||
| sem_destroy.cpp | ||
| HDRS | ||
| sem_destroy.h | ||
| DEPENDS | ||
| .posix_semaphore | ||
| libc.hdr.errno_macros | ||
| libc.include.semaphore | ||
| libc.src.errno.errno | ||
| ) | ||
|
|
||
| add_entrypoint_object( | ||
| sem_getvalue | ||
| SRCS | ||
| sem_getvalue.cpp | ||
| HDRS | ||
| sem_getvalue.h | ||
| DEPENDS | ||
| .posix_semaphore | ||
| libc.hdr.errno_macros | ||
| libc.include.semaphore | ||
| libc.src.errno.errno | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| //===-- Shared helpers for POSIX semaphores -------------------------------===// | ||
| // | ||
| // 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_SEMAPHORE_POSIX_SEMAPHORE_H | ||
| #define LLVM_LIBC_SRC_SEMAPHORE_POSIX_SEMAPHORE_H | ||
|
|
||
| #include "hdr/types/sem_t.h" | ||
| #include "src/__support/CPP/atomic.h" | ||
| #include "src/__support/common.h" | ||
| #include "src/__support/threads/linux/futex_word.h" | ||
|
|
||
| namespace LIBC_NAMESPACE_DECL { | ||
| namespace sem_utils { | ||
|
|
||
| // 0x53 = S, 0x45 = E, 0x4D = M, 0x31 = 1 | ||
| // canary value: SEM1 in hex | ||
| LIBC_INLINE_VAR constexpr unsigned int SEM_CANARY = 0x53454D31U; | ||
|
|
||
| static_assert(sizeof(__futex_word) == sizeof(FutexWordType)); | ||
| static_assert(alignof(__futex_word) >= alignof(FutexWordType)); | ||
Pengxiang-Huang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // TODO: | ||
| // 1. Add named semaphore support: sem_open, sem_close, sem_unlink | ||
| // 2. Add the posting and waiting operations: sem_post, sem_wait, | ||
| // sem_trywait, sem_timedwait, sem_clockwait. | ||
|
|
||
| LIBC_INLINE FutexWordType *value_ptr(sem_t *sem) { | ||
| return &sem->__value.__word; | ||
| } | ||
|
|
||
| // get the atomic reference for sem->__value | ||
| LIBC_INLINE cpp::AtomicRef<FutexWordType> value(sem_t *sem) { | ||
| return cpp::AtomicRef<FutexWordType>(*value_ptr(sem)); | ||
| } | ||
|
|
||
| LIBC_INLINE void initialize(sem_t *sem, unsigned int initial_value) { | ||
| // used in sem_init | ||
| // init happens before the semaphore is published to any threads | ||
| // initialize a initialized semaphore is undefined | ||
| // so RELAXED ordering is enough | ||
| value(sem).store(initial_value, cpp::MemoryOrder::RELAXED); | ||
| sem->__canary = SEM_CANARY; | ||
| for (unsigned char &byte : sem->__reserved) | ||
| byte = 0; | ||
| } | ||
|
|
||
| LIBC_INLINE bool is_valid(const sem_t *sem) { | ||
| // sanity check for a given semaphore pointer | ||
| return sem != nullptr && sem->__canary == SEM_CANARY; | ||
| } | ||
|
|
||
| LIBC_INLINE void invalidate(sem_t *sem) { | ||
| // used in sem_destroy | ||
| // invalidate is safe only when no threads is using | ||
| // blocked by destroyed semaphore is undefined | ||
| // use a destroyed semaphore is undefined | ||
| // RELAXED ordering is enough | ||
| value(sem).store(0, cpp::MemoryOrder::RELAXED); | ||
| sem->__canary = 0; | ||
| for (unsigned char &byte : sem->__reserved) | ||
| byte = 0; | ||
| } | ||
|
|
||
| } // namespace sem_utils | ||
| } // namespace LIBC_NAMESPACE_DECL | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SEMAPHORE_POSIX_SEMAPHORE_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| //===-- Implementation of sem_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 "src/semaphore/sem_destroy.h" | ||
|
|
||
| #include "src/semaphore/posix_semaphore.h" | ||
|
|
||
| #include "hdr/errno_macros.h" | ||
| #include "src/__support/common.h" | ||
| #include "src/__support/libc_errno.h" | ||
|
|
||
| namespace LIBC_NAMESPACE_DECL { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, sem_destroy, (sem_t * sem)) { | ||
| if (!sem_utils::is_valid(sem)) { | ||
| libc_errno = EINVAL; | ||
| return -1; | ||
| } | ||
|
|
||
|
||
| sem_utils::invalidate(sem); | ||
| return 0; | ||
| } | ||
|
|
||
| } // namespace LIBC_NAMESPACE_DECL | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| //===-- Implementation header for sem_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_SEMAPHORE_SEM_DESTROY_H | ||
| #define LLVM_LIBC_SRC_SEMAPHORE_SEM_DESTROY_H | ||
|
|
||
| #include "hdr/types/sem_t.h" | ||
| #include "src/__support/macros/config.h" | ||
|
|
||
| namespace LIBC_NAMESPACE_DECL { | ||
|
|
||
| int sem_destroy(sem_t *sem); | ||
|
|
||
| } // namespace LIBC_NAMESPACE_DECL | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SEMAPHORE_SEM_DESTROY_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| //===-- Implementation of sem_getvalue -----------------------------------===// | ||
| // | ||
| // 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/semaphore/sem_getvalue.h" | ||
|
|
||
| #include "src/semaphore/posix_semaphore.h" | ||
|
|
||
| #include "hdr/errno_macros.h" | ||
| #include "src/__support/common.h" | ||
| #include "src/__support/libc_errno.h" | ||
|
|
||
| namespace LIBC_NAMESPACE_DECL { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, sem_getvalue, | ||
| (sem_t *__restrict sem, int *__restrict sval)) { | ||
| if (!sem_utils::is_valid(sem) || sval == nullptr) { | ||
| libc_errno = EINVAL; | ||
| return -1; | ||
| } | ||
|
|
||
Pengxiang-Huang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // get value is informational but not a synchronization op | ||
| // RELAXED ordering is enough | ||
| *sval = | ||
| static_cast<int>(sem_utils::value(sem).load(cpp::MemoryOrder::RELAXED)); | ||
| return 0; | ||
| } | ||
|
|
||
| } // namespace LIBC_NAMESPACE_DECL | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| //===-- Implementation header for sem_getvalue -----------------*- 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_SEMAPHORE_SEM_GETVALUE_H | ||
| #define LLVM_LIBC_SRC_SEMAPHORE_SEM_GETVALUE_H | ||
|
|
||
| #include "hdr/types/sem_t.h" | ||
| #include "src/__support/macros/config.h" | ||
|
|
||
| namespace LIBC_NAMESPACE_DECL { | ||
|
|
||
| int sem_getvalue(sem_t *__restrict sem, int *__restrict sval); | ||
|
|
||
| } // namespace LIBC_NAMESPACE_DECL | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SEMAPHORE_SEM_GETVALUE_H |
Uh oh!
There was an error while loading. Please reload this page.