| /* |
| * Copyright (c) 2022 Google Inc. All rights reserved |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files |
| * (the "Software"), to deal in the Software without restriction, |
| * including without limitation the rights to use, copy, modify, merge, |
| * publish, distribute, sublicense, and/or sell copies of the Software, |
| * and to permit persons to whom the Software is furnished to do so, |
| * subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be |
| * included in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| #pragma once |
| |
| #include <kernel/event.h> |
| #include <kernel/mutex.h> |
| #include <kernel/thread.h> |
| #include <lk/compiler.h> |
| |
| _LIBCPP_BEGIN_NAMESPACE_STD |
| |
| // Mutex |
| struct __libcpp_mutex_t { |
| mutex_t __m; |
| |
| // Default constructor that can be used by _LIBCPP_MUTEX_INITIALIZER |
| constexpr __libcpp_mutex_t() noexcept : __m(MUTEX_INITIAL_VALUE(__m)) {} |
| |
| // __m is self-referential so disable copies and moves |
| __libcpp_mutex_t(const __libcpp_mutex_t&) = delete; |
| __libcpp_mutex_t(__libcpp_mutex_t&&) = delete; |
| __libcpp_mutex_t& operator=(const __libcpp_mutex_t&) = delete; |
| __libcpp_mutex_t& operator=(__libcpp_mutex_t&&) = delete; |
| }; |
| #define _LIBCPP_MUTEX_INITIALIZER (__libcpp_mutex_t()) |
| |
| #if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) |
| typedef void* __libcpp_recursive_mutex_t[6]; |
| #elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) |
| typedef void* __libcpp_recursive_mutex_t[5]; |
| #else |
| # error Unsupported architecture |
| #endif |
| |
| // Condition Variable |
| struct __libcpp_condvar_t { |
| event_t __e; |
| |
| // Default constructor that can be used by _LIBCPP_CONDVAR_INITIALIZER |
| constexpr __libcpp_condvar_t() noexcept : __e(EVENT_INITIAL_VALUE(__e, false, 0)) {} |
| |
| // __e is self-referential so disable copies and moves |
| __libcpp_condvar_t(const __libcpp_condvar_t&) = delete; |
| __libcpp_condvar_t(__libcpp_condvar_t&&) = delete; |
| __libcpp_condvar_t& operator=(const __libcpp_condvar_t&) = delete; |
| __libcpp_condvar_t& operator=(__libcpp_condvar_t&&) = delete; |
| }; |
| #define _LIBCPP_CONDVAR_INITIALIZER (__libcpp_condvar_t()) |
| |
| // Execute Once |
| typedef void* __libcpp_exec_once_flag; |
| #define _LIBCPP_EXEC_ONCE_INITIALIZER (nullptr) |
| |
| // Thread ID |
| typedef thread_t* __libcpp_thread_id; |
| |
| // Thread |
| #define _LIBCPP_NULL_THREAD (nullptr) |
| |
| typedef thread_t* __libcpp_thread_t; |
| |
| // Thread Local Storage |
| typedef long __libcpp_tls_key; |
| |
| #define _LIBCPP_TLS_DESTRUCTOR_CC |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_mutex_lock(__libcpp_mutex_t *__m) |
| { |
| mutex_acquire(&__m->__m); |
| return 0; |
| } |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_mutex_unlock(__libcpp_mutex_t *__m) |
| { |
| mutex_release(&__m->__m); |
| return 0; |
| } |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_mutex_destroy(__libcpp_mutex_t *__m); |
| |
| // Condition Variable |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_condvar_signal(__libcpp_condvar_t *__cv); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) |
| { |
| event_signal(&__cv->__e, true); |
| event_unsignal(&__cv->__e); |
| return 0; |
| } |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) |
| { |
| event_wait(&__cv->__e); |
| return 0; |
| } |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, |
| timespec *__ts); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv); |
| |
| // Thread id |
| // Returns non-zero if the thread ids are equal, otherwise 0 |
| static inline _LIBCPP_INLINE_VISIBILITY |
| bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); |
| |
| // Returns non-zero if t1 < t2, otherwise 0 |
| static inline _LIBCPP_INLINE_VISIBILITY |
| bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); |
| |
| // Thread |
| static inline _LIBCPP_INLINE_VISIBILITY |
| bool __libcpp_thread_isnull(const __libcpp_thread_t *__t); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), |
| void *__arg); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| __libcpp_thread_id __libcpp_thread_get_current_id(); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_thread_join(__libcpp_thread_t *__t); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_thread_detach(__libcpp_thread_t *__t); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| void __libcpp_thread_yield(); |
| |
| // Thread local storage |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| void *__libcpp_tls_get(__libcpp_tls_key __key); |
| |
| static inline _LIBCPP_INLINE_VISIBILITY |
| int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); |
| |
| _LIBCPP_END_NAMESPACE_STD |