@@ -94,6 +94,9 @@ extern "C" {
94
94
#elif defined(_CTHREAD_WIN32_ )
95
95
#include <windows.h>
96
96
#include <sys/timeb.h>
97
+ # ifndef usleep
98
+ # define usleep (n ) Sleep(n)
99
+ # endif
97
100
#endif
98
101
#include <time.h>
99
102
#include <stdbool.h>
@@ -259,7 +262,6 @@ typedef int (*thrd_start_t)(void *arg);
259
262
260
263
/** Create a new thread.
261
264
* @param thr Identifier of the newly created thread.
262
- * @param stacksize The initial size of the stack, in bytes.
263
265
* @param func A function pointer to the function that will be executed in
264
266
* the new thread.
265
267
* @param arg An argument to the thread function.
@@ -400,30 +402,30 @@ extern "C" {
400
402
401
403
#include "rpmalloc.h"
402
404
#if !defined(C11_MALLOC ) || !defined(C11_FREE ) || !defined(C11_REALLOC )|| !defined(C11_CALLOC )
403
- #define C11_MALLOC malloc
404
- #define C11_FREE free
405
- #define C11_REALLOC realloc
406
- #define C11_CALLOC calloc
405
+ #define C11_MALLOC malloc
406
+ #define C11_FREE free
407
+ #define C11_REALLOC realloc
408
+ #define C11_CALLOC calloc
407
409
#endif
408
410
409
411
#ifndef TIME_UTC
410
412
#define TIME_UTC 1
411
413
#endif
412
414
413
- /* Public API qualifier. */
415
+ /* Public API qualifier. */
414
416
#ifndef C_API
415
- #define C_API extern
417
+ #define C_API extern
416
418
#endif
417
419
418
420
#ifndef thrd_local
419
421
#ifdef emulate_tls
420
- # define thrd_local_return (type , var ) return (type * )tss_get(thrd_##var##_tss);
421
- # define thrd_local_get (type , var ) \
422
- type* var(void) { \
423
- if (thrd_##var##_tls == 0) { \
424
- thrd_##var##_tls = sizeof(type); \
422
+ # define thrd_local_return (type , var ) return (type)tss_get(thrd_##var##_tss);
423
+ # define thrd_local_get (type , var , initial , prefix ) \
424
+ prefix type* var(void) { \
425
+ if (thrd_##var##_tls == 0) { \
426
+ thrd_##var##_tls = sizeof(type); \
425
427
if (tss_create(&thrd_##var##_tss, C11_FREE) == thrd_success) \
426
- atexit(var##_delete); \
428
+ atexit(var##_del); \
427
429
else \
428
430
goto err; \
429
431
} \
@@ -440,83 +442,111 @@ extern "C" {
440
442
return NULL; \
441
443
}
442
444
443
- # define thrd_local_delete (type , var ) \
444
- void var##_delete(void) { \
445
- if (thrd_##var##_tls == 0) { \
446
- void *ptr = tss_get(thrd_##var##_tss); \
447
- if (ptr != NULL) \
448
- C11_FREE(ptr); \
449
- tss_delete(thrd_##var##_tss); \
450
- thrd_##var##_tss = 0; \
451
- thrd_##var##_tls = 0; \
452
- } \
445
+ # define thrd_local_del (type , var , initial , prefix ) \
446
+ prefix void var##_del(void) { \
447
+ if (thrd_##var##_tls != 0) { \
448
+ thrd_##var##_tls = 0; \
449
+ C11_FREE(tss_get(thrd_##var##_tss)); \
450
+ tss_delete(thrd_##var##_tss); \
451
+ thrd_##var##_tss = -1; \
452
+ } \
453
453
}
454
454
455
- /* Initialize and setup thread local storage `var name` as functions. */
456
- # define thrd_local (type , var ) \
457
- static type thrd_##var##_buffer; \
458
- int thrd_##var##_tls = 0; \
459
- tss_t thrd_##var##_tss = 0; \
460
- thrd_local_delete(type, var) \
461
- thrd_local_get(type, var)
462
-
463
- # define thrd_local_setup_static (type , var , initial ) \
464
- static thrd_local_get(type, var) \
465
- static FORCEINLINE void var##_update(type value) { \
466
- *var() = value; \
467
- } \
468
- static FORCEINLINE bool is_##var##_empty(void) { \
455
+ # define thrd_local_setup (type , var , initial , prefix ) \
456
+ static type thrd_##var##_buffer; \
457
+ prefix int thrd_##var##_tls = 0; \
458
+ prefix tss_t thrd_##var##_tss = 0; \
459
+ thrd_local_del(type, var, initial, prefix) \
460
+ prefix FORCEINLINE void var##_update(type value) { \
461
+ *var() = value; \
462
+ } \
463
+ prefix FORCEINLINE bool is_##var##_empty(void) { \
469
464
return is_empty(tss_get(thrd_##var##_tss)); \
470
465
}
471
466
472
- # define thrd_local_static (type , var , initial ) \
473
- static int thrd_##var##_tls = 0; \
474
- static tss_t thrd_##var##_tss = 0; \
475
- thrd_local_delete(type, var) \
476
- thrd_local_setup_static(type, var, initial)
477
-
478
- # define thrd_local_proto (type , var , prefix ) \
479
- prefix int thrd_##var##_tls; \
480
- prefix tss_t thrd_##var##_tss; \
481
- prefix type* var(void); \
482
- prefix void var##_delete(void);
483
-
484
- /* Creates a compile time thread local storage variable */
485
- # define thrd_local_create (type , var ) thrd_local_proto(type, var, C_API)
467
+ /* Initialize and setup thread local storage `var name` as functions. */
468
+ # define thrd_local (type , var , initial ) \
469
+ thrd_local_setup(type, var, initial, ) \
470
+ thrd_local_get(type, var, initial, )
471
+
472
+ # define thrd_local_plain (type , var , initial ) \
473
+ thrd_local_setup(type, var, initial, ) \
474
+ thrd_local_get(type, var, initial, )
475
+
476
+ # define thrd_static (type , var , initial ) \
477
+ thrd_local_setup(type, var, initial, static) \
478
+ thrd_local_get(type, var, initial, static)
479
+
480
+ # define thrd_static_plain (type , var , initial ) \
481
+ thrd_local_setup(type, var, initial, static) \
482
+ thrd_local_get(type, var, initial, static)
483
+
484
+ # define thrd_local_proto (type , var , prefix ) \
485
+ prefix int thrd_##var##_tls; \
486
+ prefix tss_t thrd_##var##_tss; \
487
+ prefix type var(void); \
488
+ prefix void var##_del(void); \
489
+ prefix void var##_update(type value); \
490
+ prefix bool is_##var##_empty(void);
491
+
492
+ /* Creates a `extern` compile time emulated/explict thread-local storage variable, pointer of type */
493
+ # define thrd_local_extern (type , var ) thrd_local_proto(type *, var, C_API)
494
+ /* Creates a `extern` compile time emulated/explict thread-local storage variable, non-pointer of type */
495
+ # define thrd_local_external (type , var ) thrd_local_proto(type, var, C_API)
486
496
#else
487
- # define thrd_local_return (type , var ) return (type * )thrd_##var##_tls;
488
- # define thrd_local_get (type , var ) \
489
- type* var(void) { \
490
- if (thrd_##var##_tls == NULL) \
497
+ # define thrd_local_return (type , var ) return (type)thrd_##var##_tls;
498
+ # define thrd_local_get (type , var , initial , prefix ) \
499
+ prefix FORCEINLINE type var(void) { \
500
+ if (thrd_##var##_tls == initial) { \
491
501
thrd_##var##_tls = &thrd_##var##_buffer; \
492
- thrd_local_return(type, var) \
502
+ atexit(var##_del); \
503
+ } \
504
+ thrd_local_return(type, var) \
493
505
}
494
506
495
- # define thrd_local (type , var ) \
496
- static thread_local type thrd_##var##_buffer; \
497
- thread_local type* thrd_##var##_tls = NULL; \
498
- thrd_local_get(type, var)
499
-
500
- # define thrd_local_setup_static (type , var , initial ) \
501
- static FORCEINLINE type var(void) { \
502
- return (type)thrd_##var##_tls; \
503
- } \
504
- static FORCEINLINE void var##_update(type value) { \
505
- thrd_##var##_tls = value; \
506
- } \
507
- static FORCEINLINE bool is_##var##_empty(void) { \
508
- return thrd_##var##_tls == initial; \
507
+ # define thrd_local_setup (type , var , initial , prefix ) \
508
+ prefix thread_local type thrd_##var##_tls = initial; \
509
+ prefix FORCEINLINE void var##_del(void) { \
510
+ } \
511
+ prefix FORCEINLINE void var##_update(type value) { \
512
+ thrd_##var##_tls = value; \
513
+ } \
514
+ prefix FORCEINLINE bool is_##var##_empty(void) { \
515
+ return thrd_##var##_tls == initial; \
509
516
}
510
517
511
- # define thrd_local_static (type , var , initial ) \
512
- static thread_local type thrd_##var##_tls = initial; \
513
- thrd_local_setup_static(type, var, initial)
518
+ /* Initialize and setup thread local storage `var name` as functions. */
519
+ # define thrd_local (type , var , initial ) \
520
+ static thread_local type thrd_##var##_buffer; \
521
+ thrd_local_setup(type *, var, initial, ) \
522
+ thrd_local_get(type *, var, initial, )
514
523
515
- # define thrd_local_proto (type , var , prefix ) \
516
- prefix thread_local type* thrd_##var##_tls; \
517
- prefix type* var(void);
524
+ # define thrd_local_plain (type , var , initial ) \
525
+ static thread_local type thrd_##var##_buffer; \
526
+ thrd_local_setup(type, var, initial, ) \
527
+ thrd_local_get(type, var, initial, )
518
528
519
- # define thrd_local_create (type , var ) thrd_local_proto(type, var, C_API)
529
+ # define thrd_static (type , var , initial ) \
530
+ static thread_local type thrd_##var##_buffer; \
531
+ thrd_local_setup(type *, var, initial, static) \
532
+ thrd_local_get(type *, var, initial, static)
533
+
534
+ # define thrd_static_plain (type , var , initial ) \
535
+ static thread_local type thrd_##var##_buffer; \
536
+ thrd_local_setup(type, var, initial, static) \
537
+ thrd_local_get(type, var, initial, static)
538
+
539
+ # define thrd_local_proto (type , var , prefix ) \
540
+ prefix thread_local type thrd_##var##_tls; \
541
+ prefix void var##_del(void); \
542
+ prefix void var##_update(type value); \
543
+ prefix bool is_##var##_empty(void); \
544
+ prefix type var(void);
545
+
546
+ /* Creates a native `extern` compile time thread-local storage variable, pointer of type */
547
+ # define thrd_local_extern (type , var ) thrd_local_proto(type *, var, C_API)
548
+ /* Creates a native `extern` compile time thread-local storage variable, non-pointer of type */
549
+ # define thrd_local_external (type , var ) thrd_local_proto(type, var, C_API)
520
550
#endif
521
551
#endif /* thrd_local */
522
552
0 commit comments