source: mainline/uspace/lib/cpp/include/internal/thread.hpp@ 7e7c1aac

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7e7c1aac was 9283830, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added a threading middle layer

  • Property mode set to 100644
File size: 5.0 KB
RevLine 
[9283830]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_INTERNAL_THREAD
30#define LIBCPP_INTERNAL_THREAD
31
32namespace std
33{ // TODO: fix cheaders
34 extern "C" {
35 #include <fibril.h>
36 #include <fibril_synch.h>
37 }
38}
39
40#include <chrono>
41
42namespace std::aux
43{
44 struct fibril_tag
45 { /* DUMMY BODY */ };
46
47 struct thread_tag
48 { /* DUMMY BODY */ };
49
50 template<class>
51 struct threading_policy;
52
53 template<>
54 struct threading_policy<fibril_tag>
55 {
56 using mutex_type = fibril_mutex_t;
57 using thread_type = fid_t;
58 using condvar_type = fibril_condvar_t;
59 using time_unit = suseconds_t;
60
61 struct thread
62 {
63 template<class Callable, class Payload>
64 static thread_type create(Callable clbl, Payload& pld)
65 {
66 return fibril_create(clbl, (void*)&pld);
67 }
68
69 static void start(thread_type thr)
70 {
71 fibril_add_ready(thr);
72 }
73
74 static thread_type this_thread()
75 {
76 return fibril_get_id();
77 }
78
79 static void yield()
80 {
81 fibril_yield();
82 }
83
84 /**
85 * Note: join & detach are performed at the C++
86 * level at the moment, but eventually should
87 * be moved here once joinable fibrils are in libc.
88 */
89 };
90
91 struct mutex
92 {
93 static void init(mutex_type& mtx)
94 {
95 fibril_mutex_initialize(&mtx);
96 }
97
98 static void lock(mutex_type& mtx)
99 {
100 fibril_mutex_lock(&mtx);
101 }
102
103 static void unlock(mutex_type& mtx)
104 {
105 fibril_mutex_unlock(&mtx);
106 }
107
108 static bool try_lock(mutex_type& mtx)
109 {
110 return fibril_mutex_trylock(&mtx);
111 }
112
113 static bool try_lock_for(mutex_type& mtx, time_unit timeout)
114 {
115 // TODO: we need fibril_mutex_trylock_for() :/
116 return try_lock(mtx);
117 }
118 };
119
120 struct condvar
121 {
122 static void init(condvar_type& cv)
123 {
124 fibril_condvar_initialize(&cv);
125 }
126
127 static void wait(condvar_type& cv, mutex_type& mtx)
128 {
129 fibril_condvar_wait(&cv, &mtx);
130 }
131
132 static void wait_for(condvar_type& cv, mutex_type& mtx, time_unit timeout)
133 {
134 fibril_condvar_wait_timeout(&cv, &mtx, timeout);
135 }
136
137 static void signal(condvar_type& cv)
138 {
139 fibril_condvar_signal(&cv);
140 }
141
142 static void broadcast(condvar_type& cv)
143 {
144 fibril_condvar_broadcast(&cv);
145 }
146 };
147
148 struct time
149 {
150 template<class Rep, class Period>
151 static time_unit convert(std::chrono::duration<Rep, Period> dur)
152 {
153 return std::chrono::duration_cast<std::chrono::duration<Rep, micro>>(dur).count();
154 }
155
156 static void sleep(time_unit time)
157 {
158 fibril_usleep(time);
159 }
160 };
161 };
162
163 template<>
164 struct threading_policy<thread_tag>
165 {
166 // TODO:
167 };
168
169 using default_tag = fibril_tag;
170 using threading = threading_policy<default_tag>;
171
172 using thread_t = typename threading::thread_type;
173 using mutex_t = typename threading::mutex_type;
174 using condvar_t = typename threading::condvar_type;
175 using time_unit_t = typename threading::time_unit;
176}
177
178#endif
Note: See TracBrowser for help on using the repository browser.