/* * 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 #include #include #include _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