ae2f_docs
Thrd.auto.h
Go to the documentation of this file.
1#undef __ae2f_MACRO_GENERATED
2#define __ae2f_MACRO_GENERATED 1
3/**
4 * @file Thrd.auto.h
5 *
6 * @brief
7 * Contains various implementations which could be various
8 *
9 * @details
10 *
11 * Following operations would be implemented
12 *
13 * create
14 * join
15 * sleep
16 * yield
17 * delete
18 *
19 * */
20
21#ifndef ae2f_Sys_Thrd_auto_h
22#include <ae2f/Sys/Thrd.h>
23#undef __ae2f_MACRO_GENERATED
24#define __ae2f_MACRO_GENERATED 1
25#define ae2f_Sys_Thrd_auto_h
26
27
29#else
30#include <ae2f/Macro.h>
31#undef __ae2f_MACRO_GENERATED
32#define __ae2f_MACRO_GENERATED 1
33#endif
34
35struct timespec;
36
37#if ae2f_Sys__linux(!)0
38
39#include <errno.h>
40#undef __ae2f_MACRO_GENERATED
41#define __ae2f_MACRO_GENERATED 1
42
43#define ___linux_ae2f_SysThrdMk_imp_call(
44 /** tparam */
45
46
47 /** param */
48 /* , ae2f_eSysThrd_t */ ret_stat,
49 /* ae2f_SysThrdID_t */ ret_tid,
50 /* ae2f_SysThrdFn_t* const */ prm_func,
51 /* _ae2f_SysThrdRunnerPrm_t* const */ prm_stck,
52 /* void* const */ prm_stcktop,
53 /* size_t */ prm_stcksz \
54)\
55{
56 (ret_tid) = clone(
57 ae2f_reinterpret_cast(ae2f_SysThrdFn_t*, _ae2f_SysThrdRunner)
58 , (prm_stcktop)
59 , (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
60 , (prm_stck)
61 );
62
63 if((ret_tid) == -1) {
64 (ret_stat) = ae2f_eSysThrdErr;
65
66 } else if((ret_tid) == 0)
67 {
68 syscall(SYS_exit, 0);
69 }
70 else
71 {
72 (ret_stat) = ae2f_eSysThrdSuccess;
73
74 } \
75}
76
77
78
79/**
80 * @brief
81 * Create a thread.
82 * */
83#define _ae2f_SysThrdMk_imp(
84 /** tparam */
85
86
87 /** param */
88 /* , ae2f_eSysThrd_t */ ret_stat,
89 /* ae2f_SysThrd */ ret_thrd,
90 /* ae2f_SysThrdFn_t* const */ prm_func,
91 /* void* const */ prm_arg,
92 /* const size_t */ prm_stcksz \
93)\
94{
95 (ret_thrd).m_stck.m_void = mmap(
96 NULL, ((ret_thrd).m_stcksz = (
97 (prm_stcksz)
98 + sizeof(_ae2f_SysThrdRunnerPrm_t)
99 + sizeof(void*)
100 )
101 )
102 , PROT_READ | PROT_WRITE
103 , MAP_PRIVATE | MAP_STACK | MAP_ANONYMOUS
104 , -1, 0
105 );
106
107 if(MAP_FAILED == (ret_thrd).m_stck.m_void || !(ret_thrd).m_stck.m_void) {
108 (ret_stat) = ae2f_eSysThrdMemOut;
109 (ret_thrd).m_stck.m_void = NULL;
110 }
111 else {
112 (ret_thrd).m_stck.m_prm->m_arg = (prm_arg);
113 (ret_thrd).m_stck.m_prm->m_fn = (prm_func);
114 (ret_thrd).m_stck.m_prm->m_stcksz = (ret_thrd).m_stcksz;
115
116 ___linux_ae2f_SysThrdMk_imp_call(
117 ret_stat, (ret_thrd).m_id
118 , prm_func
119 , (ret_thrd).m_stck.m_prm
120 , __ae2f_SysThrdStckTopOper(((ret_thrd).m_stck.m_char), (prm_stcksz))
121 , prm_stcksz
122 );
123
124 if(ret_stat != ae2f_eSysThrdSuccess)
125 {
126 munmap(
127 (ret_thrd).m_stck.m_void
128 , (ret_thrd).m_stcksz
129 );
130 (ret_thrd).m_stck.m_void = NULL;
131 }
132 } \
133}
134
135
136#define _ae2f_SysThrdJoin_imp(
137 /** tparam */
138
139
140 /** param */
141 /* , ae2f_eSysThrd_t */ ret_stat,
142 /* ae2f_SysThrdRes_t */ ret_rtn,
143 /* const ae2f_SysThrd */ prm_thrd \
144)\
145{
146 ae2f_SysFtxRet_t v_res;
147
148 unless((prm_thrd).m_stck.m_void) {
149 (ret_stat) = ae2f_eSysThrdErr;
150 }
151 else {
152 do {
153 if((prm_thrd).m_stck.m_prm->m_done)
154 {
155 break;
156 }
157
159 v_res
160 , &(prm_thrd).m_stck.m_prm->m_done
161 , 0
162 );
163
164 (ret_rtn) = (prm_thrd).m_stck.m_prm->m_ret;
165 munmap((prm_thrd).m_stck.m_void, (prm_thrd).m_stcksz);
166 } while(0);
167
168 if(v_res)
169 {
170 (ret_stat) = ae2f_eSysThrdErr;
171 } else {
172 (ret_stat) = ae2f_eSysThrdSuccess;
173 }
174 } \
175}
176
177#define _ae2f_SysThrdYield_imp(
178 /** tparam */
179
180
181 /** param */
182 /* */ \
183)\
184{
185 syscall(SYS_sched_yield); \
186}
187
188#define _ae2f_SysThrdSleep_imp(
189 /** tparam */
190
191
192 /** param */
193 /* , int */ ret_stat,
194 /* const struct timespec* const */ prm_req,
195 /* struct timespec* const */ prm_rem \
196)\
197{
198 (ret_stat) = syscall(SYS_nanosleep, prm_req, prm_rem); \
199}
200
201#elif ae2f_Sys_WIN(!)0
202#define _ae2f_SysThrdMk_imp(
203 /** tparam */
204
205
206 /** param */
207 /* , ae2f_eSysThrd_t */ ret_stat,
208 /* ae2f_SysThrd */ ret_thrd,
209 /* ae2f_SysThrdFn_t* const */ prm_func,
210 /* void* const */ prm_arg,
211 /* const size_t */ prm_stcksz \
212)\
213{
214 (ret_thrd).m_id =
215 CreateThread(
216 NULL
217 , prm_stcksz
218 , prm_func
219 , prm_arg
220 , STACK_SIZE_PARAM_IS_A_RESERVATION
221 , NULL
222 );
223
224 unless((ret_thrd).m_id) {
225 (ret_stat) = ae2f_eSysThrdErr;
226 } else
227 (ret_stat) = ae2f_eSysThrdSuccess; \
228}
229
230#define _ae2f_SysThrdJoin_imp(
231 /** tparam */
232
233
234 /** param */
235 /* , ae2f_eSysThrd_t */ ret_stat,
236 /* ae2f_SysThrdRes_t */ ret_rtn,
237 /* const ae2f_SysThrd */ prm_thrd \
238)\
239{
240 (ret_stat)
241 = (
242 WaitForSingleObject((prm_thrd).m_id, INFINITE)
243 && GetExitCodeThread((prm_thrd).m_id, &(ret_rtn))
244 && CloseHandle((prm_thrd).m_id)
245 ) ? ae2f_eSysThrdSuccess : ae2f_eSysThrdErr; \
246}
247
248
249
250#define _ae2f_SysThrdYield_imp(
251 /** tparam */
252
253
254 /** param */
255 /* */ \
256)\
257{
258 SwitchToThread(); \
259}
260
261#define _ae2f_SysThrdSleep_imp(
262 /** tparam */
263
264
265 /** param */
266 /* , int */ ret_stat,
267 /* const struct timespec* const */ prm_req,
268 /* struct timespec* const */ prm_rem \
269)\
270{
271 if (
272 (prm_req) == NULL ||
273 (prm_req)->tv_sec < 0 ||
274 (prm_req)->tv_nsec < 0 ||
275 (prm_req)->tv_nsec >= 1000000000
276 )
277 {
278 SetLastError(ERROR_INVALID_PARAMETER);
279 (ret_stat) = -1;
280 } else do {
281 Sleep((DWORD)((prm_req)->tv_sec * 1000 + (prm_req)->tv_nsec / 1000000));
282 if ((prm_rem) != NULL) {
283 (prm_rem)->tv_sec = 0;
284 (prm_rem)->tv_nsec = 0;
285 }
286 (ret_stat) = 0;
287 } while(0); \
288}
289
290
291
292#else
293
294/**
295 * @param prm_stacksz_unused is not used here.
296 * */
297#define _ae2f_SysThrdMk_imp(
298 /** tparam */
299
300
301 /** param */
302 /* , ae2f_eSysThrd_t */ ret_stat,
303 /* ae2f_SysThrd */ ret_thrd,
304 /* ae2f_SysThrdFn_t* const */ prm_func,
305 /* void* const */ prm_arg,
306 /* const size_t */ prm_stcksz_unused \
307)\
308{
309 (ret_stat) = pthread_create(
310 &(ret_thrd).m_id
311 , ae2f_reinterpret_cast(const pthread_attr_t*, NULL)
312 , prm_func
313 , prm_arg
314 );
315
316 switch(ret_stat) {
317 case 0:
318 (ret_stat) = ae2f_eSysThrdSuccess;
319 break;
320
321 case EAGAIN:
322 (ret_stat) = ae2f_eSysThrdMemOut;
323 break;
324
325 case EINVAL:
326 case EPERM:
327 default:
328 (ret_stat) = ae2f_eSysThrdErr;
329 break;
330 } \
331}
332
333#define _ae2f_SysThrdJoin_imp(
334 /** tparam */
335
336
337 /** param */
338 /* , ae2f_eSysThrd_t */ ret_stat,
339 /* ae2f_SysThrdRes_t */ ret_rtn,
340 /* ae2f_SysThrd */ ref_thrd \
341)\
342{
343 switch(pthread_join((ref_thrd).m_id, &(ret_rtn)))
344 {
345 case EDEADLK:
346 (ret_stat) = ae2f_eSysThrdBusy;
347 break;
348 case EINVAL:
349 (ret_stat) = (ae2f_eSysThrdErr);
350 break;
351 case ESRCH:
352 (ret_stat) = (ae2f_eSysThrdMemOut);
353 break;
354 case 0:
355 (ret_stat) = ae2f_eSysThrdSuccess;
356 break;
357 } \
358}
359
360
361#define _ae2f_SysThrdSleep_imp(
362 /** tparam */
363
364
365 /** param */
366 /* , int */ ret_stat,
367 /* const struct timespec* const */ prm_req,
368 /* struct timespec* const */ prm_rem \
369)\
370{
371 (ret_stat) = nanosleep(prm_req, prm_rem); \
372}
373
374#define _ae2f_SysThrdYield_imp(
375 /** tparam */
376
377
378 /** param */
379 /* */ \
380)\
381{
382 sched_yield(); \
383}
384
385#endif
386#endif
387
388#undef __ae2f_MACRO_GENERATED
389
390#define __ae2f_MACRO_GENERATED 0
#define ae2f_structdef(key, name)
Definition Cast.h:110
#define ae2f_reinterpret_cast(t, v)
Definition Cast.h:52
#define unless(...)
Invokes when condition is false.
Definition Cast.h:103
#define __ae2f_MACRO_GENERATED
Definition Conv.auto.h:2
#define _ae2f_SysFtxWait(ret_err, prm_uaddr, prm_val)
Definition Ftx.auto.h:109
#define _ae2f_SysFtxWakeOne(ret_err, prm_uaddr)
Definition Ftx.auto.h:147
_ae2f_SysFtxRet_t ae2f_SysFtxRet_t
State for futex operation.
Definition Ftx.h:22
_ae2f_SysFtxEl_t ae2f_SysFtxEl_t
Futex address element type.
Definition Ftx.h:13
#define ae2f_Sys__linux
Definition Sys.h:14
#define ae2f_Sys_WIN
Definition Sys.h:17
#define _ae2f_SysThrdJoin_imp(ret_stat, ret_rtn, ref_thrd)
Definition Thrd.auto.h:333
#define _ae2f_SysThrdYield_imp()
Definition Thrd.auto.h:374
#define _ae2f_SysThrdSleep_imp(ret_stat, prm_req, prm_rem)
Definition Thrd.auto.h:361
#define ae2f_Sys_Thrd_auto_h
Definition Thrd.auto.h:25
#define _ae2f_SysThrdMk_imp(ret_stat, ret_thrd, prm_func, prm_arg, prm_stcksz_unused)
Definition Thrd.auto.h:297
#define _ae2f_SysThrdID_t
Definition Thrd.core.h:93
#define _ae2f_SysThrdPrm_t
Definition Thrd.core.h:92
#define _ae2f_SysThrdRes_t
Definition Thrd.core.h:91
ae2f_eSysThrd_t
enum values related to thread. 't follows C11 thread standard.
Definition Thrd.h:33
@ ae2f_eSysThrdTmOut
Definition Thrd.h:41
@ 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_SysThrdPrm_t ae2f_SysThrdPrm_t
Parameters for thread.
Definition Thrd.h:18
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
#define ae2f_MAC(...)
Definition mac.h:28