• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Google Inc. All rights reserved
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#pragma once
24
25#include <kernel/event.h>
26#include <kernel/mutex.h>
27#include <kernel/thread.h>
28#include <lk/compiler.h>
29
30_LIBCPP_BEGIN_NAMESPACE_STD
31
32// Mutex
33struct __libcpp_mutex_t {
34  mutex_t __m;
35
36  // Default constructor that can be used by _LIBCPP_MUTEX_INITIALIZER
37  constexpr __libcpp_mutex_t() noexcept : __m(MUTEX_INITIAL_VALUE(__m)) {}
38
39  // __m is self-referential so disable copies and moves
40  __libcpp_mutex_t(const __libcpp_mutex_t&) = delete;
41  __libcpp_mutex_t(__libcpp_mutex_t&&) = delete;
42  __libcpp_mutex_t& operator=(const __libcpp_mutex_t&) = delete;
43  __libcpp_mutex_t& operator=(__libcpp_mutex_t&&) = delete;
44};
45#define _LIBCPP_MUTEX_INITIALIZER (__libcpp_mutex_t())
46
47#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
48typedef void* __libcpp_recursive_mutex_t[6];
49#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
50typedef void* __libcpp_recursive_mutex_t[5];
51#else
52# error Unsupported architecture
53#endif
54
55// Condition Variable
56struct __libcpp_condvar_t {
57  event_t __e;
58
59  // Default constructor that can be used by _LIBCPP_CONDVAR_INITIALIZER
60  constexpr __libcpp_condvar_t() noexcept : __e(EVENT_INITIAL_VALUE(__e, false, 0)) {}
61
62  // __e is self-referential so disable copies and moves
63  __libcpp_condvar_t(const __libcpp_condvar_t&) = delete;
64  __libcpp_condvar_t(__libcpp_condvar_t&&) = delete;
65  __libcpp_condvar_t& operator=(const __libcpp_condvar_t&) = delete;
66  __libcpp_condvar_t& operator=(__libcpp_condvar_t&&) = delete;
67};
68#define _LIBCPP_CONDVAR_INITIALIZER (__libcpp_condvar_t())
69
70// Execute Once
71typedef void* __libcpp_exec_once_flag;
72#define _LIBCPP_EXEC_ONCE_INITIALIZER (nullptr)
73
74// Thread ID
75typedef thread_t* __libcpp_thread_id;
76
77// Thread
78#define _LIBCPP_NULL_THREAD (nullptr)
79
80typedef thread_t* __libcpp_thread_t;
81
82// Thread Local Storage
83typedef long __libcpp_tls_key;
84
85#define _LIBCPP_TLS_DESTRUCTOR_CC
86
87static inline _LIBCPP_INLINE_VISIBILITY
88int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
89
90static inline _LIBCPP_INLINE_VISIBILITY
91int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
92
93static inline _LIBCPP_INLINE_VISIBILITY
94bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
95
96static inline _LIBCPP_INLINE_VISIBILITY
97int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
98
99static inline _LIBCPP_INLINE_VISIBILITY
100int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
101
102static inline _LIBCPP_INLINE_VISIBILITY
103int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
104{
105  mutex_acquire(&__m->__m);
106  return 0;
107}
108
109static inline _LIBCPP_INLINE_VISIBILITY
110bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
111
112static inline _LIBCPP_INLINE_VISIBILITY
113int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
114{
115  mutex_release(&__m->__m);
116  return 0;
117}
118
119static inline _LIBCPP_INLINE_VISIBILITY
120int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
121
122// Condition Variable
123static inline _LIBCPP_INLINE_VISIBILITY
124int __libcpp_condvar_signal(__libcpp_condvar_t *__cv);
125
126static inline _LIBCPP_INLINE_VISIBILITY
127int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
128{
129  event_signal(&__cv->__e, true);
130  event_unsignal(&__cv->__e);
131  return 0;
132}
133
134static inline _LIBCPP_INLINE_VISIBILITY
135int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
136{
137  event_wait(&__cv->__e);
138  return 0;
139}
140
141static inline _LIBCPP_INLINE_VISIBILITY
142int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
143                               timespec *__ts);
144
145static inline _LIBCPP_INLINE_VISIBILITY
146int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv);
147
148// Thread id
149// Returns non-zero if the thread ids are equal, otherwise 0
150static inline _LIBCPP_INLINE_VISIBILITY
151bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
152
153// Returns non-zero if t1 < t2, otherwise 0
154static inline _LIBCPP_INLINE_VISIBILITY
155bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
156
157// Thread
158static inline _LIBCPP_INLINE_VISIBILITY
159bool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
160
161static inline _LIBCPP_INLINE_VISIBILITY
162int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
163                           void *__arg);
164
165static inline _LIBCPP_INLINE_VISIBILITY
166__libcpp_thread_id __libcpp_thread_get_current_id();
167
168static inline _LIBCPP_INLINE_VISIBILITY
169__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
170
171static inline _LIBCPP_INLINE_VISIBILITY
172int __libcpp_thread_join(__libcpp_thread_t *__t);
173
174static inline _LIBCPP_INLINE_VISIBILITY
175int __libcpp_thread_detach(__libcpp_thread_t *__t);
176
177static inline _LIBCPP_INLINE_VISIBILITY
178void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
179
180static inline _LIBCPP_INLINE_VISIBILITY
181void __libcpp_thread_yield();
182
183// Thread local storage
184static inline _LIBCPP_INLINE_VISIBILITY
185int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *));
186
187static inline _LIBCPP_INLINE_VISIBILITY
188void *__libcpp_tls_get(__libcpp_tls_key __key);
189
190static inline _LIBCPP_INLINE_VISIBILITY
191int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
192
193_LIBCPP_END_NAMESPACE_STD
194