Advertisement
Chris_M_Thomasson

Pre-Alpha Limited C11 Threading Emulation

Jun 27th, 2015
370
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.19 KB | None | 0 0
  1. #if ! defined (CT_C11_THREADS_H_EMULATION_H)
  2. #   define CT_C11_THREADS_H_EMULATION_H 1
  3. #   if defined (__cplusplus)
  4.         extern "C"
  5.         {
  6. #   endif
  7.  
  8.  
  9.  
  10. #if defined (CT_C11_THREADS_H_PRINTF_LOG)
  11. #   include <stdio.h>
  12. #   define CT_C11_THREADS_H_PRINTF(mp_exp) printf mp_exp
  13. #else
  14. #   define CT_C11_THREADS_H_PRINTF(mp_exp) ((void)(0))
  15. #endif
  16.  
  17.  
  18.  
  19.  
  20. #include <stdlib.h>
  21. #include <pthread.h>
  22. #include <assert.h>
  23.  
  24.  
  25. typedef int (*ct_thrd_start_t) (void*);
  26.  
  27. struct ct_thrd_user
  28. {
  29.     pthread_t ptid;
  30. };
  31.  
  32.  
  33. struct ct_thrd_sys
  34. {
  35.     ct_thrd_start_t fp_user;
  36.     void* user_ctx;
  37.     int user_ret;
  38. };
  39.  
  40.  
  41. enum ct_thrd_sys_status
  42. {
  43.     ct_thrd_success = 0,
  44.     ct_thrd_nomem = 1,
  45.     ct_thrd_timedout = 2,
  46.     ct_thrd_busy = 3,
  47.     ct_thrd_error = 4
  48. };
  49.  
  50.  
  51.  
  52.  
  53.  
  54. /* low-level system threading API's
  55. __________________________________________________________________*/
  56. static struct ct_thrd_sys*
  57. ct_thrd_sys_create(
  58.     ct_thrd_start_t fp_user,
  59.     void* user_ctx
  60. );
  61.  
  62. static void
  63. ct_thrd_sys_destroy(
  64.     struct ct_thrd_sys* const self
  65. );
  66.  
  67. static void*
  68. ct_thrd_sys_entry(
  69.     void* self_raw
  70. );
  71.  
  72.  
  73.  
  74. struct ct_thrd_sys*
  75. ct_thrd_sys_create(
  76.     ct_thrd_start_t fp_user,
  77.     void* user_ctx
  78. ){
  79.     struct ct_thrd_sys* const self = malloc(sizeof(*self));
  80.  
  81.     if (self)
  82.     {
  83.         self->fp_user = fp_user;
  84.         self->user_ctx = user_ctx;
  85.         self->user_ret = 0;
  86.     }
  87.  
  88.     CT_C11_THREADS_H_PRINTF(("ct_thrd_sys_create = %p\r\n", (void*)self));
  89.  
  90.     return self;
  91. }
  92.  
  93. void
  94. ct_thrd_sys_destroy(
  95.     struct ct_thrd_sys* const self
  96. ){
  97.     free(self);
  98.  
  99.     CT_C11_THREADS_H_PRINTF(
  100.         ("ct_thrd_sys_destroy(self = %p)\r\n", (void*)self)
  101.     );
  102. }
  103.  
  104.  
  105. void*
  106. ct_thrd_sys_entry(
  107.     void* self_raw
  108. ){
  109.     struct ct_thrd_sys* const self = self_raw;
  110.  
  111.     CT_C11_THREADS_H_PRINTF(
  112.         ("ct_thrd_sys_entry(self_raw = %p):Enter\r\n", self_raw)
  113.     );
  114.  
  115.     self->user_ret = self->fp_user(self->user_ctx);
  116.  
  117.     CT_C11_THREADS_H_PRINTF(
  118.         ("ct_thrd_sys_entry(self_raw = %p):Exit = %p\r\n", self_raw, (void*)self)
  119.     );
  120.  
  121.     return self;
  122. }
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129. /* C11 emulation API layer
  130. __________________________________________________________________*/
  131.  
  132.  
  133. /* Threading API
  134. ______________________________________________________________*/
  135. typedef struct ct_thrd_user ct_thrd_t;
  136.  
  137.  
  138. static int
  139. ct_thrd_create(
  140.     ct_thrd_t* uself,
  141.     ct_thrd_start_t fp_user,
  142.     void* user_ctx
  143. );
  144.  
  145. static int
  146. ct_thrd_join(
  147.     ct_thrd_t self,
  148.     int* user_retv
  149. );
  150.  
  151.  
  152. int
  153. ct_thrd_create(
  154.     ct_thrd_t* uself,
  155.     ct_thrd_start_t fp_user,
  156.     void* user_ctx
  157. ){
  158.     struct ct_thrd_sys* const self =
  159.         ct_thrd_sys_create(fp_user, user_ctx);
  160.  
  161.     if (self)
  162.     {
  163.         int status = pthread_create(&uself->ptid, NULL, ct_thrd_sys_entry, self);
  164.  
  165.         if (! status)
  166.         {
  167.             return ct_thrd_success;
  168.         }
  169.  
  170.         ct_thrd_sys_destroy(self);
  171.     }
  172.  
  173.     return ct_thrd_nomem;
  174. }
  175.  
  176.  
  177. int
  178. ct_thrd_join(
  179.     ct_thrd_t self,
  180.     int* user_retv
  181. ){
  182.     void* ptjret = NULL;
  183.  
  184.     pthread_join(self.ptid, &ptjret);
  185.  
  186.     if (ptjret)
  187.     {
  188.         struct ct_thrd_sys* const self = ptjret;
  189.  
  190.         if (user_retv)
  191.         {
  192.             *user_retv = self->user_ret;
  193.         }
  194.  
  195.         ct_thrd_sys_destroy(self);
  196.  
  197.         return ct_thrd_success;
  198.     }
  199.  
  200.     return ct_thrd_error;
  201. }
  202.  
  203.  
  204.  
  205.  
  206. /* Thread Specific Storage API
  207. ______________________________________________________________*/
  208. typedef pthread_key_t ct_tss_t;
  209. typedef void(*ct_tss_dtor_t) (void*);
  210.  
  211. static int
  212. ct_tss_create(
  213.     ct_tss_t* self,
  214.     ct_tss_dtor_t fp_user_dtor
  215. );
  216.  
  217. static void
  218. ct_tss_delete(
  219.     ct_tss_t self
  220. );
  221.  
  222. static int
  223. ct_tss_set(
  224.     ct_tss_t self,
  225.     void* user_ctx
  226. );
  227.  
  228. #define ct_tss_get(mp_self) pthread_getspecific((mp_self))
  229.  
  230.  
  231.  
  232. int
  233. ct_tss_create(
  234.     ct_tss_t* self,
  235.     ct_tss_dtor_t fp_user_dtor
  236. ){
  237.     int status = pthread_key_create(self, fp_user_dtor);
  238.  
  239.     if (!status)
  240.     {
  241.         return ct_thrd_success;
  242.     }
  243.  
  244.     return ct_thrd_error;
  245. }
  246.  
  247.  
  248. void
  249. ct_tss_delete(
  250.     ct_tss_t self
  251. ){
  252.     int status = pthread_key_delete(self);
  253.  
  254.     if (! status)
  255.     {
  256.         return;
  257.     }
  258.  
  259.     assert(! status);
  260. }
  261.  
  262.  
  263. int
  264. ct_tss_set(
  265.     ct_tss_t self,
  266.     void* user_ctx
  267. ){
  268.     int status = pthread_setspecific(self, user_ctx);
  269.  
  270.     if (!status)
  271.     {
  272.         return ct_thrd_success;
  273.     }
  274.  
  275.     return ct_thrd_error;
  276. }
  277.  
  278.  
  279.  
  280.  
  281. /* Mutex API
  282. ______________________________________________________________*/
  283. typedef pthread_mutex_t ct_mtx_t;
  284.  
  285. enum {
  286.     ct_mtx_plain = 1,
  287.     ct_mtx_recursive = 2,
  288.     ct_mtx_timed = 4
  289. };
  290.  
  291.  
  292. int
  293. ct_mtx_init(
  294.     ct_mtx_t* self,
  295.     int type
  296. ){
  297.     if (type == ct_mtx_plain)
  298.     {
  299.         int status = pthread_mutex_init(self, NULL);
  300.  
  301.         if (! status)
  302.         {
  303.             return ct_thrd_success;
  304.         }
  305.     }
  306.  
  307.     return ct_thrd_error;
  308. }
  309.  
  310.  
  311. void
  312. ct_mtx_destroy(
  313.     ct_mtx_t* self
  314. ){
  315.     int status = pthread_mutex_destroy(self);
  316.  
  317.     if (! status)
  318.     {
  319.         return;
  320.     }
  321.  
  322.     assert(! status);
  323. }
  324.  
  325.  
  326. int
  327. ct_mtx_lock(
  328.     ct_mtx_t* self
  329. ){
  330.     int status = pthread_mutex_lock(self);
  331.  
  332.     if (! status)
  333.     {
  334.         return ct_thrd_success;
  335.     }
  336.  
  337.     assert(! status);
  338.  
  339.     return ct_thrd_error;
  340. }
  341.  
  342.  
  343. int
  344. ct_mtx_unlock(
  345.     ct_mtx_t* self
  346. ){
  347.     int status = pthread_mutex_unlock(self);
  348.  
  349.     if (!status)
  350.     {
  351.         return ct_thrd_success;
  352.     }
  353.  
  354.     assert(! status);
  355.  
  356.     return ct_thrd_error;
  357. }
  358.  
  359.  
  360.  
  361.  
  362. /* Mutex API
  363. ______________________________________________________________*/
  364. typedef pthread_cond_t ct_cnd_t;
  365.  
  366. int
  367. ct_cnd_init(
  368.     ct_cnd_t* self
  369. ){
  370.     int status = pthread_cond_init(self, NULL);
  371.  
  372.     if (! status)
  373.     {
  374.         return ct_thrd_success;
  375.     }
  376.  
  377.     return ct_thrd_error;
  378. }
  379.  
  380.  
  381. void
  382. ct_cnd_destroy(
  383.     ct_cnd_t* self
  384. ){
  385.     int status = pthread_cond_destroy(self);
  386.  
  387.     if (! status)
  388.     {
  389.         return;
  390.     }
  391.  
  392.     assert(! status);
  393. }
  394.  
  395.  
  396. int
  397. ct_cnd_signal(
  398.     ct_cnd_t* self
  399. ){
  400.     int status = pthread_cond_signal(self);
  401.  
  402.     if (! status)
  403.     {
  404.         return ct_thrd_success;
  405.     }
  406.  
  407.     assert(! status);
  408.  
  409.     return ct_thrd_error;
  410. }
  411.  
  412.  
  413. int
  414. ct_cnd_broadcast(
  415.     ct_cnd_t* self
  416. ){
  417.     int status = pthread_cond_broadcast(self);
  418.  
  419.     if (! status)
  420.     {
  421.         return ct_thrd_success;
  422.     }
  423.  
  424.     assert(! status);
  425.  
  426.     return ct_thrd_error;
  427. }
  428.  
  429.  
  430. int
  431. ct_cnd_wait(
  432.     ct_cnd_t* self,
  433.     ct_mtx_t* mtx
  434. ){
  435.     int status = pthread_cond_wait(self, mtx);
  436.  
  437.     if (! status)
  438.     {
  439.         return ct_thrd_success;
  440.     }
  441.  
  442.     assert(! status);
  443.  
  444.     return ct_thrd_error;
  445. }
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452. /* Mock up the final C11 API with some macros...  ;^o
  453. ______________________________________________________________*/
  454.  
  455.  
  456.  
  457. /* C11 threading API
  458. _________________________________________________*/
  459. #define thrd_success    ct_thrd_success
  460. #define thrd_nomem      ct_thrd_nomem
  461. #define thrd_timedout   ct_thrd_timedout
  462. #define thrd_busy       ct_thrd_busy
  463. #define thrd_error      ct_thrd_error
  464.  
  465. #define thrd_t          ct_thrd_t
  466.  
  467. #define thrd_create     ct_thrd_create
  468. #define thrd_join       ct_thrd_join
  469.  
  470.  
  471.  
  472. /* C11 thread specific storage API
  473. _________________________________________________*/
  474. #define tss_t           ct_tss_t
  475.  
  476. #define tss_create      ct_tss_create
  477. #define tss_delete      ct_tss_delete
  478. #define tss_set         ct_tss_set
  479. #define tss_get         ct_tss_get
  480.  
  481.  
  482.  
  483. /* C11 mutex API
  484. _________________________________________________*/
  485. #define mtx_plain       ct_mtx_plain
  486. #define mtx_recursive   ct_mtx_recursive
  487. #define mtx_timed       ct_mtx_timed
  488.  
  489. #define mtx_t           ct_mtx_t
  490.  
  491. #define mtx_init        ct_mtx_init
  492. #define mtx_destroy     ct_mtx_destroy
  493. #define mtx_lock        ct_mtx_lock
  494. #define mtx_unlock      ct_mtx_unlock
  495.  
  496.  
  497.  
  498. /* C11 condition variable API
  499. _________________________________________________*/
  500. #define cnd_t           ct_cnd_t
  501.  
  502. #define cnd_init        ct_cnd_init
  503. #define cnd_destroy     ct_cnd_destroy
  504. #define cnd_signal      ct_cnd_signal
  505. #define cnd_broadcast   ct_cnd_broadcast
  506. #define cnd_wait        ct_cnd_wait
  507.  
  508.  
  509.  
  510.  
  511. #   if defined (__cplusplus)
  512.         }
  513. #   endif
  514. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement