blob: 985120a3f9d09b6ea79b4f30c8f5245d963dce43 [file]
/*
* 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