ae2f_docs
Loading...
Searching...
No Matches
Thrd.def.c
1/**
2 * @file Thrd.auto.h
3 *
4 * @brief
5 * Contains various implementations which could be various
6 *
7 * @details
8 *
9 * Following operations would be implemented
10 *
11 * create
12 * join
13 * sleep
14 * yield
15 * delete
16 *
17 * */
18
19#ifndef ae2f_Sys_Thrd_auto_h
20#include <ae2f/Sys/Thrd.h>
21#define ae2f_Sys_Thrd_auto_h
22
23
24
25struct timespec;
26
27#if ae2f_Sys__linux(!)0
28
29#include <errno.h>
30
31#undef ae2f_prmvoid
32
34#define ae2f_prmvoid
35#else
36#define ae2f_prmvoid void
37#endif
38
39
40#include <ae2f/Macro.h>
41
42ae2f_MAC() __linux_ae2f_SysThrdMk_imp_call(
43 ae2f_eSysThrd_t ret_stat,
44 ae2f_SysThrdID_t ret_tid,
45 _ae2f_SysThrdRunnerPrm_t* const prm_stck,
46 void* const prm_stcktop
47 )
48{
49 (ret_tid) = clone(
50 ae2f_reinterpret_cast(ae2f_SysThrdFn_t*, _ae2f_SysThrdRunner)
51 , (prm_stcktop)
52 , (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
53 , (prm_stck)
54 );
55
56 if((ret_tid) == -1) {
57 (ret_stat) = ae2f_eSysThrdErr;
58
59 } else if((ret_tid) == 0)
60 {
61 syscall(SYS_exit, 0);
62 }
63 else
64 {
65 (ret_stat) = ae2f_eSysThrdSuccess;
66
67 }
68}
69
70
71
72/**
73 * @brief
74 * Create a thread.
75 * */
76ae2f_MAC() ae2f_SysThrdMk_imp(
77 ae2f_eSysThrd_t ret_stat,
78 ae2f_SysThrd ret_thrd,
79 ae2f_SysThrdFn_t* const prm_func,
80 void* const prm_arg,
81 const size_t prm_stcksz
82 )
83{
84 (ret_thrd).m_stck.m_void = mmap(
85 ae2f_NIL, ((ret_thrd).m_stcksz = (
86 (prm_stcksz)
87 + ae2f_static_cast(size_t, sizeof(_ae2f_SysThrdRunnerPrm_t))
88 + ae2f_static_cast(size_t, sizeof(void*))
89 )
90 )
91 , PROT_READ | PROT_WRITE
92 , MAP_PRIVATE | MAP_STACK | MAP_ANONYMOUS
93 , -1, 0
94 );
95
96 if(MAP_FAILED == (ret_thrd).m_stck.m_void || !(ret_thrd).m_stck.m_void) {
97 (ret_stat) = ae2f_eSysThrdMemOut;
98 (ret_thrd).m_stck.m_void = ae2f_NIL;
99 (ret_thrd).m_id = -1;
100 }
101 else {
102 (ret_thrd).m_stck.m_prm->m_arg = (prm_arg);
103 (ret_thrd).m_stck.m_prm->m_fn = (prm_func);
104 (ret_thrd).m_stck.m_prm->m_stcksz = (ret_thrd).m_stcksz;
105
106 ___linux_ae2f_SysThrdMk_imp_call(
107 ret_stat, (ret_thrd).m_id
108 , (ret_thrd).m_stck.m_prm
109 , __ae2f_SysThrdStckTopOper(((ret_thrd).m_stck.m_char), (prm_stcksz))
110 );
111
112 if(ret_stat != ae2f_eSysThrdSuccess)
113 {
114 munmap(
115 (ret_thrd).m_stck.m_void
116 , (ret_thrd).m_stcksz
117 );
118 (ret_thrd).m_stck.m_void = ae2f_NIL;
119 }
120 }
121}
122
123
124ae2f_MAC() ae2f_SysThrdJoin_imp(
125 ae2f_eSysThrd_t ret_stat,
126 ae2f_SysThrdRes_t ret_rtn,
127 const ae2f_SysThrd prm_thrd
128 )
129{
130 ae2f_eSysFtxWait v_res = ae2f_SysFtxWait_GOOD;
131
132 unless((prm_thrd).m_stck.m_void) {
133 (ret_stat) = ae2f_eSysThrdErr;
134 }
135 else {
136 do {
137 if((prm_thrd).m_stck.m_prm->m_done)
138 {
139 break;
140 }
141
143 v_res
144 , &(prm_thrd).m_stck.m_prm->m_done
145 , 0
146 );
147
148 (ret_rtn) = (prm_thrd).m_stck.m_prm->m_ret;
149 munmap((prm_thrd).m_stck.m_void, (prm_thrd).m_stcksz);
150 } while(0);
151
152 if(v_res)
153 {
154 (ret_stat) = ae2f_eSysThrdErr;
155 } else {
156 (ret_stat) = ae2f_eSysThrdSuccess;
157 }
158 }
159}
160
161ae2f_MAC() ae2f_SysThrdYield_imp(void)
162{
163 syscall(SYS_sched_yield);
164}
165
166ae2f_MAC() ae2f_SysThrdSleep_imp(
167 long ret_stat
168 , const struct timespec * const prm_req
169 , struct timespec * const prm_rem
170 )
171{
172 (ret_stat) = syscall(SYS_nanosleep, prm_req, prm_rem);
173}
174
175#elif ae2f_Sys_WIN(!)0
176ae2f_MAC() ae2f_SysThrdMk_imp(
177 ae2f_eSysThrd_t ret_stat,
178 ae2f_SysThrd ret_thrd,
179 ae2f_SysThrdFn_t* const prm_func,
180 void* const prm_arg,
181 const size_t prm_stcksz
182 )
183{
184 (ret_thrd).m_id =
185 CreateThread(
186 NULL
187 , prm_stcksz
188 , prm_func
189 , prm_arg
190 , STACK_SIZE_PARAM_IS_A_RESERVATION
191 , NULL
192 );
193
194 unless((ret_thrd).m_id) {
195 (ret_stat) = ae2f_eSysThrdErr;
196 } else
197 (ret_stat) = ae2f_eSysThrdSuccess;
198}
199
200ae2f_MAC() ae2f_SysThrdJoin_imp(
201 ae2f_eSysThrd_t ret_stat,
202 ae2f_SysThrdRes_t ret_rtn,
203 const ae2f_SysThrd prm_thrd
204 )
205{
206 (ret_stat)
207 = (
208 WaitForSingleObject((prm_thrd).m_id, INFINITE)
209 && GetExitCodeThread((prm_thrd).m_id, &(ret_rtn))
210 && CloseHandle((prm_thrd).m_id)
211 ) ? ae2f_eSysThrdSuccess : ae2f_eSysThrdErr;
212}
213
214
215
216ae2f_MAC() ae2f_SysThrdYield_imp()
217{
218 SwitchToThread();
219}
220
221ae2f_MAC() ae2f_SysThrdSleep_imp(
222 int ret_stat
223 , const struct timespec * const prm_req
224 , struct timespec * const prm_rem
225 )
226{
227 if (
228 (prm_req) == NULL ||
229 (prm_req)->tv_sec < 0 ||
230 (prm_req)->tv_nsec < 0 ||
231 (prm_req)->tv_nsec >= 1000000000
232 )
233 {
234 SetLastError(ERROR_INVALID_PARAMETER);
235 (ret_stat) = -1;
236 } else do {
237 Sleep((DWORD)((prm_req)->tv_sec * 1000 + (prm_req)->tv_nsec / 1000000));
238 if ((prm_rem) != NULL) {
239 (prm_rem)->tv_sec = 0;
240 (prm_rem)->tv_nsec = 0;
241 }
242 (ret_stat) = 0;
243 } while(0);
244}
245
246
247
248#else
249
250/**
251 * @param prm_stacksz_unused is not used here.
252 * */
253ae2f_MAC() ae2f_SysThrdMk_imp(
254 ae2f_eSysThrd_t ret_stat,
255 ae2f_SysThrd ret_thrd,
256 ae2f_SysThrdFn_t* const prm_func,
257 void* const prm_arg,
258 const size_t prm_stcksz_unused
259 )
260{
261 (ret_stat) = pthread_create(
262 &(ret_thrd).m_id
263 , ae2f_reinterpret_cast(const pthread_attr_t*, NULL)
264 , prm_func
265 , prm_arg
266 );
267
268 switch(ret_stat) {
269 case 0:
270 (ret_stat) = ae2f_eSysThrdSuccess;
271 break;
272
273 case EAGAIN:
274 (ret_stat) = ae2f_eSysThrdMemOut;
275 break;
276
277 case EINVAL:
278 case EPERM:
279 default:
280 (ret_stat) = ae2f_eSysThrdErr;
281 break;
282 }
283}
284
285ae2f_MAC() ae2f_SysThrdJoin_imp(
286 ae2f_eSysThrd_t ret_stat,
287 ae2f_SysThrdRes_t ret_rtn,
288 ae2f_SysThrd ref_thrd
289 )
290{
291 switch(pthread_join((ref_thrd).m_id, &(ret_rtn)))
292 {
293 case EDEADLK:
294 (ret_stat) = ae2f_eSysThrdBusy;
295 break;
296 case EINVAL:
297 (ret_stat) = (ae2f_eSysThrdErr);
298 break;
299 case ESRCH:
300 (ret_stat) = (ae2f_eSysThrdMemOut);
301 break;
302 case 0:
303 (ret_stat) = ae2f_eSysThrdSuccess;
304 break;
305 }
306}
307
308
309ae2f_MAC() ae2f_SysThrdSleep_imp(
310 int ret_stat
311 , const struct timespec * const prm_req
312 , struct timespec * const prm_rem
313 )
314{
315 (ret_stat) = nanosleep(prm_req, prm_rem);
316}
317
318ae2f_MAC() ae2f_SysThrdYield_imp()
319{
320 sched_yield();
321}
322
323#endif
324#endif
#define ae2f_static_cast(t, v)
static_cast for C++
Definition Cast.h:28
#define ae2f_reinterpret_cast(t, v)
reinterpret_cast for C++
Definition Cast.h:36
@ ae2f_SysFtxWait_GOOD
Succesful.
Definition Ftx.core.h:22
#define _ae2f_SysFtxWait(ret_err, pprm_uaddr, prm_val)
Definition Ftx.h:53
#define unless(a)
Invokes when condition is false.
Definition Keys.h:34
#define __ae2f_MACRO_GENERATED
Definition Macro.h:4
#define ae2f_MAC(a)
A hint for creating a macro from void-returning function.
Definition Macro.h:17
#define ae2f_NIL
Definition Nil.h:13
#define ae2f_Sys__linux
Value expected did not match.
Definition Sys.h:15
@ ae2f_eSysThrdMemOut
Definition Thrd.h:38
@ ae2f_eSysThrdSuccess
Definition Thrd.h:35
_ae2f_SysThrdRes_t ae2f_SysThrdRes_t
Return type for thread.
Definition Thrd.h:14
ae2f_SysThrdRes_t ae2f_SysThrdFn_t(ae2f_SysThrdPrm_t)
Thread starting function type.
Definition Thrd.h:25
_ae2f_SysThrdID_t ae2f_SysThrdID_t
Thread ID.
Definition Thrd.h:22
ae2f_SysThrdID_t m_id
Definition Thrd.h:55