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