0009-Replace-thread-local-with-pthread-TSD.patch 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. From 2b9087215fe11e22b4e29369cedca7579ac605bc Mon Sep 17 00:00:00 2001
  2. From: Thomas Guillem <thomas@gllm.fr>
  3. Date: Mon, 17 Jul 2017 17:03:24 +0200
  4. Subject: [PATCH 09/26] Replace thread local with pthread TSD
  5. ---
  6. src/misc/interrupt.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
  7. src/misc/variables.c | 19 ++++++++++++++
  8. 2 files changed, 78 insertions(+)
  9. diff --git a/src/misc/interrupt.c b/src/misc/interrupt.c
  10. index 7004ed2c3a..65607cdcd3 100644
  11. --- a/src/misc/interrupt.c
  12. +++ b/src/misc/interrupt.c
  13. @@ -43,13 +43,26 @@
  14. #include "interrupt.h"
  15. #include "libvlc.h"
  16. +#ifdef I_CAN_HAZ_TSD
  17. static thread_local vlc_interrupt_t *vlc_interrupt_var;
  18. +#else
  19. +#include <pthread.h>
  20. +static pthread_key_t vlc_interrupt_var_key;
  21. +static pthread_once_t vlc_interrupt_var_key_once = PTHREAD_ONCE_INIT;
  22. +static void vlc_interrupt_var_key_create()
  23. +{
  24. + pthread_key_create(&vlc_interrupt_var_key, NULL);
  25. +}
  26. +#endif
  27. /**
  28. * Initializes an interruption context.
  29. */
  30. void vlc_interrupt_init(vlc_interrupt_t *ctx)
  31. {
  32. +#ifndef I_CAN_HAZ_TSD
  33. + pthread_once(&vlc_interrupt_var_key_once, vlc_interrupt_var_key_create);
  34. +#endif
  35. vlc_mutex_init(&ctx->lock);
  36. ctx->interrupted = false;
  37. atomic_init(&ctx->killed, false);
  38. @@ -98,9 +111,15 @@ void vlc_interrupt_raise(vlc_interrupt_t *ctx)
  39. vlc_interrupt_t *vlc_interrupt_set(vlc_interrupt_t *newctx)
  40. {
  41. +#ifdef I_CAN_HAZ_TSD
  42. vlc_interrupt_t *oldctx = vlc_interrupt_var;
  43. vlc_interrupt_var = newctx;
  44. +#else
  45. + vlc_interrupt_t *oldctx = pthread_getspecific(vlc_interrupt_var_key);
  46. +
  47. + pthread_setspecific(vlc_interrupt_var_key, newctx);
  48. +#endif
  49. return oldctx;
  50. }
  51. @@ -115,7 +134,11 @@ static void vlc_interrupt_prepare(vlc_interrupt_t *ctx,
  52. void (*cb)(void *), void *data)
  53. {
  54. assert(ctx != NULL);
  55. +#ifdef I_CAN_HAZ_TSD
  56. assert(ctx == vlc_interrupt_var);
  57. +#else
  58. + assert(ctx == pthread_getspecific(vlc_interrupt_var_key));
  59. +#endif
  60. vlc_mutex_lock(&ctx->lock);
  61. assert(ctx->callback == NULL);
  62. @@ -143,7 +166,11 @@ static int vlc_interrupt_finish(vlc_interrupt_t *ctx)
  63. int ret = 0;
  64. assert(ctx != NULL);
  65. +#ifdef I_CAN_HAZ_TSD
  66. assert(ctx == vlc_interrupt_var);
  67. +#else
  68. + assert(ctx == pthread_getspecific(vlc_interrupt_var_key));
  69. +#endif
  70. /* Wait for pending callbacks to prevent access by other threads. */
  71. vlc_mutex_lock(&ctx->lock);
  72. @@ -159,14 +186,22 @@ static int vlc_interrupt_finish(vlc_interrupt_t *ctx)
  73. void vlc_interrupt_register(void (*cb)(void *), void *opaque)
  74. {
  75. +#ifdef I_CAN_HAZ_TSD
  76. vlc_interrupt_t *ctx = vlc_interrupt_var;
  77. +#else
  78. + vlc_interrupt_t *ctx = pthread_getspecific(vlc_interrupt_var_key);
  79. +#endif
  80. if (ctx != NULL)
  81. vlc_interrupt_prepare(ctx, cb, opaque);
  82. }
  83. int vlc_interrupt_unregister(void)
  84. {
  85. +#ifdef I_CAN_HAZ_TSD
  86. vlc_interrupt_t *ctx = vlc_interrupt_var;
  87. +#else
  88. + vlc_interrupt_t *ctx = pthread_getspecific(vlc_interrupt_var_key);
  89. +#endif
  90. return (ctx != NULL) ? vlc_interrupt_finish(ctx) : 0;
  91. }
  92. @@ -185,7 +220,11 @@ void vlc_interrupt_kill(vlc_interrupt_t *ctx)
  93. bool vlc_killed(void)
  94. {
  95. +#ifdef I_CAN_HAZ_TSD
  96. vlc_interrupt_t *ctx = vlc_interrupt_var;
  97. +#else
  98. + vlc_interrupt_t *ctx = pthread_getspecific(vlc_interrupt_var_key);
  99. +#endif
  100. return (ctx != NULL) && atomic_load(&ctx->killed);
  101. }
  102. @@ -197,7 +236,11 @@ static void vlc_interrupt_sem(void *opaque)
  103. int vlc_sem_wait_i11e(vlc_sem_t *sem)
  104. {
  105. +#ifdef I_CAN_HAZ_TSD
  106. vlc_interrupt_t *ctx = vlc_interrupt_var;
  107. +#else
  108. + vlc_interrupt_t *ctx = pthread_getspecific(vlc_interrupt_var_key);
  109. +#endif
  110. if (ctx == NULL)
  111. return vlc_sem_wait(sem), 0;
  112. @@ -227,7 +270,11 @@ static void vlc_mwait_i11e_cleanup(void *opaque)
  113. int vlc_mwait_i11e(mtime_t deadline)
  114. {
  115. +#ifdef I_CAN_HAZ_TSD
  116. vlc_interrupt_t *ctx = vlc_interrupt_var;
  117. +#else
  118. + vlc_interrupt_t *ctx = pthread_getspecific(vlc_interrupt_var_key);
  119. +#endif
  120. if (ctx == NULL)
  121. return mwait(deadline), 0;
  122. @@ -262,7 +309,11 @@ void vlc_interrupt_forward_start(vlc_interrupt_t *to, void *data[2])
  123. {
  124. data[0] = data[1] = NULL;
  125. +#ifdef I_CAN_HAZ_TSD
  126. vlc_interrupt_t *from = vlc_interrupt_var;
  127. +#else
  128. + vlc_interrupt_t *from = pthread_getspecific(vlc_interrupt_var_key);
  129. +#endif
  130. if (from == NULL)
  131. return;
  132. @@ -371,7 +422,11 @@ static int vlc_poll_i11e_inner(struct pollfd *restrict fds, unsigned nfds,
  133. int vlc_poll_i11e(struct pollfd *fds, unsigned nfds, int timeout)
  134. {
  135. +#ifdef I_CAN_HAZ_TSD
  136. vlc_interrupt_t *ctx = vlc_interrupt_var;
  137. +#else
  138. + vlc_interrupt_t *ctx = pthread_getspecific(vlc_interrupt_var_key);
  139. +#endif
  140. if (ctx == NULL)
  141. return poll(fds, nfds, timeout);
  142. @@ -568,7 +623,11 @@ static void vlc_poll_i11e_cleanup(void *opaque)
  143. int vlc_poll_i11e(struct pollfd *fds, unsigned nfds, int timeout)
  144. {
  145. +#ifdef I_CAN_HAZ_TSD
  146. vlc_interrupt_t *ctx = vlc_interrupt_var;
  147. +#else
  148. + vlc_interrupt_t *ctx = pthread_getspecific(vlc_interrupt_var_key);
  149. +#endif
  150. if (ctx == NULL)
  151. return vlc_poll(fds, nfds, timeout);
  152. diff --git a/src/misc/variables.c b/src/misc/variables.c
  153. index 810c8ffc81..3d2d2f1dc8 100644
  154. --- a/src/misc/variables.c
  155. +++ b/src/misc/variables.c
  156. @@ -1378,7 +1378,17 @@ void DumpVariables(vlc_object_t *obj)
  157. vlc_mutex_unlock(&vlc_internals(obj)->var_lock);
  158. }
  159. +#ifdef I_CAN_HAZ_TSD
  160. static thread_local void *twalk_ctx;
  161. +#else
  162. +#include <pthread.h>
  163. +static pthread_key_t twalk_ctx_key;
  164. +static pthread_once_t twalk_ctx_key_once = PTHREAD_ONCE_INIT;
  165. +static void twalk_ctx_key_create()
  166. +{
  167. + pthread_key_create(&twalk_ctx_key, NULL);
  168. +}
  169. +#endif
  170. static void TwalkGetNames(const void *data, const VISIT which, const int depth)
  171. {
  172. @@ -1387,7 +1397,11 @@ static void TwalkGetNames(const void *data, const VISIT which, const int depth)
  173. (void) depth;
  174. const variable_t *var = *(const variable_t **)data;
  175. +#ifdef I_CAN_HAZ_TSD
  176. DECL_ARRAY(char *) *names = twalk_ctx;
  177. +#else
  178. + DECL_ARRAY(char *) *names = pthread_getspecific(twalk_ctx_key);
  179. +#endif
  180. char *dup = strdup(var->psz_name);
  181. if (dup != NULL)
  182. ARRAY_APPEND(*names, dup);
  183. @@ -1400,7 +1414,12 @@ char **var_GetAllNames(vlc_object_t *obj)
  184. DECL_ARRAY(char *) names;
  185. ARRAY_INIT(names);
  186. +#ifdef I_CAN_HAZ_TSD
  187. twalk_ctx = &names;
  188. +#else
  189. + pthread_once(&twalk_ctx_key_once, twalk_ctx_key_create);
  190. + pthread_setspecific(twalk_ctx_key, &names);
  191. +#endif
  192. vlc_mutex_lock(&priv->var_lock);
  193. twalk(priv->var_root, TwalkGetNames);
  194. vlc_mutex_unlock(&priv->var_lock);
  195. --
  196. 2.20.1