Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -r -b -C 3 ocaml-3.12.1-orig/otherlibs/systhreads/st_posix.h ocaml-3.12.1/otherlibs/systhreads/st_posix.h
- *** ocaml-3.12.1-orig/otherlibs/systhreads/st_posix.h 2010-04-27 09:55:08.000000000 +0200
- --- ocaml-3.12.1/otherlibs/systhreads/st_posix.h 2011-10-17 22:28:30.875215007 +0200
- ***************
- *** 66,78 ****
- #define ST_THREAD_FUNCTION void *
- - /* Cleanup at thread exit */
- -
- - static INLINE void st_thread_cleanup(void)
- - {
- - return;
- - }
- -
- /* Thread termination */
- static void st_thread_exit(void)
- --- 66,71 ----
- ***************
- *** 119,147 ****
- all risks of busy-waiting. Also, we count the number of waiting
- threads. */
- typedef struct {
- pthread_mutex_t lock; /* to protect contents */
- int busy; /* 0 = free, 1 = taken */
- volatile int waiters; /* number of threads waiting on master lock */
- pthread_cond_t is_free; /* signaled when free */
- } st_masterlock;
- static void st_masterlock_init(st_masterlock * m)
- {
- pthread_mutex_init(&m->lock, NULL);
- pthread_cond_init(&m->is_free, NULL);
- m->busy = 1;
- m->waiters = 0;
- }
- static void st_masterlock_acquire(st_masterlock * m)
- {
- pthread_mutex_lock(&m->lock);
- ! while (m->busy) {
- m->waiters ++;
- ! pthread_cond_wait(&m->is_free, &m->lock);
- m->waiters --;
- }
- m->busy = 1;
- pthread_mutex_unlock(&m->lock);
- }
- --- 112,206 ----
- all risks of busy-waiting. Also, we count the number of waiting
- threads. */
- +
- + typedef struct st_condition_stack {
- + pthread_cond_t cond;
- + struct st_condition_stack* next;
- + } st_condition_stack;
- +
- + typedef struct st_masterlock_queue {
- + struct st_masterlock_queue *next;
- + st_condition_stack *cond;
- + } st_masterlock_queue;
- +
- typedef struct {
- pthread_mutex_t lock; /* to protect contents */
- int busy; /* 0 = free, 1 = taken */
- volatile int waiters; /* number of threads waiting on master lock */
- pthread_cond_t is_free; /* signaled when free */
- + st_masterlock_queue queue; /* queue of waiting threads */
- + st_masterlock_queue* last; /* last in queue of waiting threads */
- } st_masterlock;
- + /* Cleanup at thread exit */
- +
- + static INLINE void st_thread_cleanup(st_masterlock *m)
- + {
- + pthread_mutex_lock(&m->lock);
- + if( m->queue.cond != NULL ){
- + pthread_cond_destroy( & m->queue.cond->cond );
- + m->queue.cond = m->queue.cond->next;
- + }
- + pthread_mutex_unlock(&m->lock);
- + return;
- + }
- +
- static void st_masterlock_init(st_masterlock * m)
- {
- pthread_mutex_init(&m->lock, NULL);
- pthread_cond_init(&m->is_free, NULL);
- m->busy = 1;
- m->waiters = 0;
- + m->queue.next = NULL;
- + m->last = & m->queue;
- + m->queue.cond = NULL;
- }
- static void st_masterlock_acquire(st_masterlock * m)
- {
- pthread_mutex_lock(&m->lock);
- !
- ! /* If another thread as already taken the master lock (busy == 1),
- ! or other threads are waiting for the master lock, we need to wait
- ! for the signal. */
- !
- ! if( m->busy == 1 || m->waiters > 0 ){
- !
- ! /* Use the local stack to get a uniq identifier for this thread,
- ! i.e. a pointer to a cons cell for the list of waiting threads. */
- ! st_masterlock_queue this_queue = { .next = NULL, .cond = NULL };
- !
- ! /* If there is already another thread waiting for the lock, put
- ! this thread at the end of the waiting queue. */
- ! m->last->next = & this_queue;
- ! m->last = &this_queue;
- ! /* Check if we are on top of the waiting queue. If yes, keep the
- ! lock, otherwise wait for another signal. Either busy==1, in
- ! which case we have been woken up for nothing by the broadcast,
- ! or busy ==0, in which case we can test if we are on top of
- ! queue.
- ! */
- !
- ! if(m->queue.cond == NULL){
- ! m->queue.cond = (struct st_condition_stack*)
- ! malloc(sizeof(struct st_condition_stack));
- ! m->queue.cond->next = NULL;
- ! pthread_cond_init(&m->queue.cond->cond, NULL);
- ! }
- ! this_queue.cond = m->queue.cond;
- ! m->queue.cond = m->queue.cond->next;
- !
- ! while( m->busy == 1 || m->queue.next != &this_queue ){
- m->waiters ++;
- ! pthread_cond_wait(&this_queue.cond->cond, &m->lock);
- m->waiters --;
- }
- + /* Put the next thread on top of the queue. */
- + if( m->last == &this_queue ){ m->last = & m->queue; }
- + m->queue.next = this_queue.next;
- + this_queue.cond->next = m->queue.cond;
- + m->queue.cond = this_queue.cond;
- + }
- m->busy = 1;
- pthread_mutex_unlock(&m->lock);
- }
- ***************
- *** 150,157 ****
- {
- pthread_mutex_lock(&m->lock);
- m->busy = 0;
- pthread_mutex_unlock(&m->lock);
- - pthread_cond_signal(&m->is_free);
- }
- static INLINE int st_masterlock_waiters(st_masterlock * m)
- --- 209,218 ----
- {
- pthread_mutex_lock(&m->lock);
- m->busy = 0;
- + if( m->waiters > 0 ){
- + pthread_cond_signal(& m->queue.next->cond->cond);
- + }
- pthread_mutex_unlock(&m->lock);
- }
- static INLINE int st_masterlock_waiters(st_masterlock * m)
- diff -r -b -C 3 ocaml-3.12.1-orig/otherlibs/systhreads/st_stubs.c ocaml-3.12.1/otherlibs/systhreads/st_stubs.c
- *** ocaml-3.12.1-orig/otherlibs/systhreads/st_stubs.c 2010-12-22 14:39:00.000000000 +0100
- --- ocaml-3.12.1/otherlibs/systhreads/st_stubs.c 2011-10-17 22:25:14.845215006 +0200
- ***************
- *** 461,467 ****
- /* Remove th from the doubly-linked list of threads and free its info block */
- caml_thread_remove_info(curr_thread);
- /* OS-specific cleanups */
- ! st_thread_cleanup();
- /* Release the runtime system */
- st_masterlock_release(&caml_master_lock);
- }
- --- 461,467 ----
- /* Remove th from the doubly-linked list of threads and free its info block */
- caml_thread_remove_info(curr_thread);
- /* OS-specific cleanups */
- ! st_thread_cleanup(&caml_master_lock);
- /* Release the runtime system */
- st_masterlock_release(&caml_master_lock);
- }
- diff -r -b -C 3 ocaml-3.12.1-orig/otherlibs/systhreads/st_win32.h ocaml-3.12.1/otherlibs/systhreads/st_win32.h
- *** ocaml-3.12.1-orig/otherlibs/systhreads/st_win32.h 2010-04-27 09:55:08.000000000 +0200
- --- ocaml-3.12.1/otherlibs/systhreads/st_win32.h 2011-10-17 22:27:27.665215002 +0200
- ***************
- *** 68,81 ****
- #define ST_THREAD_FUNCTION DWORD WINAPI
- - /* Cleanup at thread exit */
- -
- - static void st_thread_cleanup(void)
- - {
- - HANDLE ev = (HANDLE) TlsGetValue(st_thread_sem_key);
- - if (ev != NULL) CloseHandle(ev);
- - }
- -
- /* Thread termination */
- static void st_thread_exit(void)
- --- 68,73 ----
- ***************
- *** 125,130 ****
- --- 117,130 ----
- typedef CRITICAL_SECTION st_masterlock;
- + /* Cleanup at thread exit */
- +
- + static void st_thread_cleanup(st_masterlock *m)
- + {
- + HANDLE ev = (HANDLE) TlsGetValue(st_thread_sem_key);
- + if (ev != NULL) CloseHandle(ev);
- + }
- +
- static void st_masterlock_init(st_masterlock * m)
- {
- TRACE("st_masterlock_init");
Add Comment
Please, Sign In to add comment