Guest User

Untitled

a guest
Feb 16th, 2019
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.81 KB | None | 0 0
  1. diff -r -b -C 3 ocaml-3.12.1-orig/otherlibs/systhreads/st_posix.h ocaml-3.12.1/otherlibs/systhreads/st_posix.h
  2. *** ocaml-3.12.1-orig/otherlibs/systhreads/st_posix.h 2010-04-27 09:55:08.000000000 +0200
  3. --- ocaml-3.12.1/otherlibs/systhreads/st_posix.h 2011-10-17 22:28:30.875215007 +0200
  4. ***************
  5. *** 66,78 ****
  6.  
  7. #define ST_THREAD_FUNCTION void *
  8.  
  9. - /* Cleanup at thread exit */
  10. -
  11. - static INLINE void st_thread_cleanup(void)
  12. - {
  13. - return;
  14. - }
  15. -
  16. /* Thread termination */
  17.  
  18. static void st_thread_exit(void)
  19. --- 66,71 ----
  20. ***************
  21. *** 119,147 ****
  22. all risks of busy-waiting. Also, we count the number of waiting
  23. threads. */
  24.  
  25. typedef struct {
  26. pthread_mutex_t lock; /* to protect contents */
  27. int busy; /* 0 = free, 1 = taken */
  28. volatile int waiters; /* number of threads waiting on master lock */
  29. pthread_cond_t is_free; /* signaled when free */
  30. } st_masterlock;
  31.  
  32. static void st_masterlock_init(st_masterlock * m)
  33. {
  34. pthread_mutex_init(&m->lock, NULL);
  35. pthread_cond_init(&m->is_free, NULL);
  36. m->busy = 1;
  37. m->waiters = 0;
  38. }
  39.  
  40. static void st_masterlock_acquire(st_masterlock * m)
  41. {
  42. pthread_mutex_lock(&m->lock);
  43. ! while (m->busy) {
  44. m->waiters ++;
  45. ! pthread_cond_wait(&m->is_free, &m->lock);
  46. m->waiters --;
  47. }
  48. m->busy = 1;
  49. pthread_mutex_unlock(&m->lock);
  50. }
  51. --- 112,206 ----
  52. all risks of busy-waiting. Also, we count the number of waiting
  53. threads. */
  54.  
  55. +
  56. + typedef struct st_condition_stack {
  57. + pthread_cond_t cond;
  58. + struct st_condition_stack* next;
  59. + } st_condition_stack;
  60. +
  61. + typedef struct st_masterlock_queue {
  62. + struct st_masterlock_queue *next;
  63. + st_condition_stack *cond;
  64. + } st_masterlock_queue;
  65. +
  66. typedef struct {
  67. pthread_mutex_t lock; /* to protect contents */
  68. int busy; /* 0 = free, 1 = taken */
  69. volatile int waiters; /* number of threads waiting on master lock */
  70. pthread_cond_t is_free; /* signaled when free */
  71. + st_masterlock_queue queue; /* queue of waiting threads */
  72. + st_masterlock_queue* last; /* last in queue of waiting threads */
  73. } st_masterlock;
  74.  
  75. + /* Cleanup at thread exit */
  76. +
  77. + static INLINE void st_thread_cleanup(st_masterlock *m)
  78. + {
  79. + pthread_mutex_lock(&m->lock);
  80. + if( m->queue.cond != NULL ){
  81. + pthread_cond_destroy( & m->queue.cond->cond );
  82. + m->queue.cond = m->queue.cond->next;
  83. + }
  84. + pthread_mutex_unlock(&m->lock);
  85. + return;
  86. + }
  87. +
  88. static void st_masterlock_init(st_masterlock * m)
  89. {
  90. pthread_mutex_init(&m->lock, NULL);
  91. pthread_cond_init(&m->is_free, NULL);
  92. m->busy = 1;
  93. m->waiters = 0;
  94. + m->queue.next = NULL;
  95. + m->last = & m->queue;
  96. + m->queue.cond = NULL;
  97. }
  98.  
  99. static void st_masterlock_acquire(st_masterlock * m)
  100. {
  101. pthread_mutex_lock(&m->lock);
  102. !
  103. ! /* If another thread as already taken the master lock (busy == 1),
  104. ! or other threads are waiting for the master lock, we need to wait
  105. ! for the signal. */
  106. !
  107. ! if( m->busy == 1 || m->waiters > 0 ){
  108. !
  109. ! /* Use the local stack to get a uniq identifier for this thread,
  110. ! i.e. a pointer to a cons cell for the list of waiting threads. */
  111. ! st_masterlock_queue this_queue = { .next = NULL, .cond = NULL };
  112. !
  113. ! /* If there is already another thread waiting for the lock, put
  114. ! this thread at the end of the waiting queue. */
  115. ! m->last->next = & this_queue;
  116. ! m->last = &this_queue;
  117. ! /* Check if we are on top of the waiting queue. If yes, keep the
  118. ! lock, otherwise wait for another signal. Either busy==1, in
  119. ! which case we have been woken up for nothing by the broadcast,
  120. ! or busy ==0, in which case we can test if we are on top of
  121. ! queue.
  122. ! */
  123. !
  124. ! if(m->queue.cond == NULL){
  125. ! m->queue.cond = (struct st_condition_stack*)
  126. ! malloc(sizeof(struct st_condition_stack));
  127. ! m->queue.cond->next = NULL;
  128. ! pthread_cond_init(&m->queue.cond->cond, NULL);
  129. ! }
  130. ! this_queue.cond = m->queue.cond;
  131. ! m->queue.cond = m->queue.cond->next;
  132. !
  133. ! while( m->busy == 1 || m->queue.next != &this_queue ){
  134. m->waiters ++;
  135. ! pthread_cond_wait(&this_queue.cond->cond, &m->lock);
  136. m->waiters --;
  137. }
  138. + /* Put the next thread on top of the queue. */
  139. + if( m->last == &this_queue ){ m->last = & m->queue; }
  140. + m->queue.next = this_queue.next;
  141. + this_queue.cond->next = m->queue.cond;
  142. + m->queue.cond = this_queue.cond;
  143. + }
  144. m->busy = 1;
  145. pthread_mutex_unlock(&m->lock);
  146. }
  147. ***************
  148. *** 150,157 ****
  149. {
  150. pthread_mutex_lock(&m->lock);
  151. m->busy = 0;
  152. pthread_mutex_unlock(&m->lock);
  153. - pthread_cond_signal(&m->is_free);
  154. }
  155.  
  156. static INLINE int st_masterlock_waiters(st_masterlock * m)
  157. --- 209,218 ----
  158. {
  159. pthread_mutex_lock(&m->lock);
  160. m->busy = 0;
  161. + if( m->waiters > 0 ){
  162. + pthread_cond_signal(& m->queue.next->cond->cond);
  163. + }
  164. pthread_mutex_unlock(&m->lock);
  165. }
  166.  
  167. static INLINE int st_masterlock_waiters(st_masterlock * m)
  168. diff -r -b -C 3 ocaml-3.12.1-orig/otherlibs/systhreads/st_stubs.c ocaml-3.12.1/otherlibs/systhreads/st_stubs.c
  169. *** ocaml-3.12.1-orig/otherlibs/systhreads/st_stubs.c 2010-12-22 14:39:00.000000000 +0100
  170. --- ocaml-3.12.1/otherlibs/systhreads/st_stubs.c 2011-10-17 22:25:14.845215006 +0200
  171. ***************
  172. *** 461,467 ****
  173. /* Remove th from the doubly-linked list of threads and free its info block */
  174. caml_thread_remove_info(curr_thread);
  175. /* OS-specific cleanups */
  176. ! st_thread_cleanup();
  177. /* Release the runtime system */
  178. st_masterlock_release(&caml_master_lock);
  179. }
  180. --- 461,467 ----
  181. /* Remove th from the doubly-linked list of threads and free its info block */
  182. caml_thread_remove_info(curr_thread);
  183. /* OS-specific cleanups */
  184. ! st_thread_cleanup(&caml_master_lock);
  185. /* Release the runtime system */
  186. st_masterlock_release(&caml_master_lock);
  187. }
  188. diff -r -b -C 3 ocaml-3.12.1-orig/otherlibs/systhreads/st_win32.h ocaml-3.12.1/otherlibs/systhreads/st_win32.h
  189. *** ocaml-3.12.1-orig/otherlibs/systhreads/st_win32.h 2010-04-27 09:55:08.000000000 +0200
  190. --- ocaml-3.12.1/otherlibs/systhreads/st_win32.h 2011-10-17 22:27:27.665215002 +0200
  191. ***************
  192. *** 68,81 ****
  193.  
  194. #define ST_THREAD_FUNCTION DWORD WINAPI
  195.  
  196. - /* Cleanup at thread exit */
  197. -
  198. - static void st_thread_cleanup(void)
  199. - {
  200. - HANDLE ev = (HANDLE) TlsGetValue(st_thread_sem_key);
  201. - if (ev != NULL) CloseHandle(ev);
  202. - }
  203. -
  204. /* Thread termination */
  205.  
  206. static void st_thread_exit(void)
  207. --- 68,73 ----
  208. ***************
  209. *** 125,130 ****
  210. --- 117,130 ----
  211.  
  212. typedef CRITICAL_SECTION st_masterlock;
  213.  
  214. + /* Cleanup at thread exit */
  215. +
  216. + static void st_thread_cleanup(st_masterlock *m)
  217. + {
  218. + HANDLE ev = (HANDLE) TlsGetValue(st_thread_sem_key);
  219. + if (ev != NULL) CloseHandle(ev);
  220. + }
  221. +
  222. static void st_masterlock_init(st_masterlock * m)
  223. {
  224. TRACE("st_masterlock_init");
Add Comment
Please, Sign In to add comment