source: mainline/uspace/lib/cpp/include/__bits/thread/threading.hpp@ 5f97ef44

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5f97ef44 was 5f97ef44, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Sleep is more natural as part of the fibril API.
(the implementation will move later)

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_BITS_THREAD_THREADING
30#define LIBCPP_BITS_THREAD_THREADING
31
32namespace std::hel
33{
34 extern "C" {
35 #include <async.h>
36 #include <fibril.h>
37 #include <fibril_synch.h>
38 }
39}
40
41#include <chrono>
42
43namespace std::aux
44{
45 struct fibril_tag
46 { /* DUMMY BODY */ };
47
48 struct thread_tag
49 { /* DUMMY BODY */ };
50
51 template<class>
52 struct threading_policy;
53
54 template<>
55 struct threading_policy<fibril_tag>
56 {
57 using mutex_type = hel::fibril_mutex_t;
58 using thread_type = hel::fid_t;
59 using condvar_type = hel::fibril_condvar_t;
60 using time_unit = hel::suseconds_t;
61 using shared_mutex_type = hel::fibril_rwlock_t;
62
63 struct thread
64 {
65 template<class Callable, class Payload>
66 static thread_type create(Callable clbl, Payload& pld)
67 {
68 return hel::fibril_create(clbl, (void*)&pld);
69 }
70
71 static void start(thread_type thr)
72 {
73 hel::fibril_add_ready(thr);
74 }
75
76 static thread_type this_thread()
77 {
78 return hel::fibril_get_id();
79 }
80
81 static void yield()
82 {
83 hel::fibril_yield();
84 }
85
86 /**
87 * Note: join & detach are performed at the C++
88 * level at the moment, but eventually should
89 * be moved here once joinable fibrils are in libc.
90 */
91 };
92
93 struct mutex
94 {
95 static void init(mutex_type& mtx)
96 {
97 hel::fibril_mutex_initialize(&mtx);
98 }
99
100 static void lock(mutex_type& mtx)
101 {
102 hel::fibril_mutex_lock(&mtx);
103 }
104
105 static void unlock(mutex_type& mtx)
106 {
107 hel::fibril_mutex_unlock(&mtx);
108 }
109
110 static bool try_lock(mutex_type& mtx)
111 {
112 return hel::fibril_mutex_trylock(&mtx);
113 }
114
115 static bool try_lock_for(mutex_type& mtx, time_unit timeout)
116 {
117 // TODO: we need fibril_mutex_trylock_for() :/
118 return try_lock(mtx);
119 }
120 };
121
122 struct condvar
123 {
124 static void init(condvar_type& cv)
125 {
126 hel::fibril_condvar_initialize(&cv);
127 }
128
129 static void wait(condvar_type& cv, mutex_type& mtx)
130 {
131 hel::fibril_condvar_wait(&cv, &mtx);
132 }
133
134 static int wait_for(condvar_type& cv, mutex_type& mtx, time_unit timeout)
135 {
136 return hel::fibril_condvar_wait_timeout(&cv, &mtx, timeout);
137 }
138
139 static void signal(condvar_type& cv)
140 {
141 hel::fibril_condvar_signal(&cv);
142 }
143
144 static void broadcast(condvar_type& cv)
145 {
146 hel::fibril_condvar_broadcast(&cv);
147 }
148 };
149
150 struct time
151 {
152 template<class Rep, class Period>
153 static time_unit convert(const std::chrono::duration<Rep, Period>& dur)
154 {
155 return std::chrono::duration_cast<std::chrono::duration<Rep, micro>>(dur).count();
156 }
157
158 static void sleep(time_unit time)
159 {
160 hel::fibril_usleep(time);
161 }
162 };
163
164 struct shared_mutex
165 {
166 static void init(shared_mutex_type& mtx)
167 {
168 hel::fibril_rwlock_initialize(&mtx);
169 }
170
171 static void lock(shared_mutex_type& mtx)
172 {
173 hel::fibril_rwlock_write_lock(&mtx);
174 }
175
176 static void unlock(shared_mutex_type& mtx)
177 {
178 hel::fibril_rwlock_write_unlock(&mtx);
179 }
180
181 static void lock_shared(shared_mutex_type& mtx)
182 {
183 hel::fibril_rwlock_read_lock(&mtx);
184 }
185
186 static void unlock_shared(shared_mutex_type& mtx)
187 {
188 hel::fibril_rwlock_read_unlock(&mtx);
189 }
190
191 static bool try_lock(shared_mutex_type& mtx)
192 {
193 // TODO: rwlocks don't have try locking capabilities
194 lock(mtx);
195
196 return true;
197 }
198
199 static bool try_lock_shared(shared_mutex_type& mtx)
200 {
201 lock(mtx);
202
203 return true;
204 }
205
206 static bool try_lock_for(shared_mutex_type& mtx, time_unit timeout)
207 {
208 return try_lock(mtx);
209 }
210
211 static bool try_lock_shared_for(shared_mutex_type& mtx, time_unit timeout)
212 {
213 return try_lock(mtx);
214 }
215 };
216 };
217
218 template<>
219 struct threading_policy<thread_tag>
220 {
221 // TODO:
222 };
223
224 using default_tag = fibril_tag;
225 using threading = threading_policy<default_tag>;
226
227 using thread_t = typename threading::thread_type;
228 using mutex_t = typename threading::mutex_type;
229 using condvar_t = typename threading::condvar_type;
230 using time_unit_t = typename threading::time_unit;
231 using shared_mutex_t = typename threading::shared_mutex_type;
232}
233
234#endif
Note: See TracBrowser for help on using the repository browser.