Issue #150 - Inefficient (but working) thread-join!

This commit is contained in:
Justin Ethier 2017-06-17 01:36:47 -04:00
parent 64be028166
commit c550b15f3a
4 changed files with 39 additions and 14 deletions

View file

@ -176,7 +176,7 @@
(flush-output-port (current-output-port))) (flush-output-port (current-output-port)))
))) )))
(define *running-threads* 0) (define *running-threads* '())
(define m (make-mutex)) (define m (make-mutex))
(define (async-exec-multi! n thunk) (define (async-exec-multi! n thunk)
@ -185,22 +185,27 @@
(async-exec! thunk))) (async-exec! thunk)))
(define (async-exec! thunk) (define (async-exec! thunk)
(set! *running-threads* (+ *running-threads* 1)) ;; On main thread, so no lock (let ((t (make-thread
(thread-start!
(make-thread
(lambda () (lambda ()
(thunk)
(mutex-lock! m) (mutex-lock! m)
(set! *running-threads* (- *running-threads* 1)) (set! *running-threads* (cons (current-thread) *running-threads*))
(mutex-unlock! m))))) (mutex-unlock! m)
(thunk)))))
(thread-start! t)))
(define (wait-for-all-async) (define (wait-for-all-async)
(let loop ((done #f)) (thread-sleep! 1) ;; TODO: not good enough, figure out a better solution
(thread-sleep! 0) (let loop ()
(define t #f)
(mutex-lock! m) (mutex-lock! m)
(if (= *running-threads* 0) (set! done #t)) (when (not (null? *running-threads*))
(set! t (car *running-threads*))
(set! *running-threads* (cdr *running-threads*)))
(mutex-unlock! m) (mutex-unlock! m)
(if (not done) (loop #f))))
(when t
(thread-join! t)
(loop))))
;;; The following code is appended to all benchmarks. ;;; The following code is appended to all benchmarks.

13
gc.c
View file

@ -1832,6 +1832,19 @@ void *collector_main(void *arg)
return NULL; return NULL;
} }
/**
* @brief A high-resolution sleep function.
*
* @param ms Sleep time in milliseconds
*/
void gc_sleep_ms(int ms)
{
struct timespec tim;
tim.tv_sec = 0;
tim.tv_nsec = ms * NANOSECONDS_PER_MILLISECOND;
nanosleep(&tim, NULL);
}
static pthread_t collector_thread; static pthread_t collector_thread;
/** /**

View file

@ -307,6 +307,7 @@ void gc_initialize(void);
void gc_add_mutator(gc_thread_data * thd); void gc_add_mutator(gc_thread_data * thd);
void gc_remove_mutator(gc_thread_data * thd); void gc_remove_mutator(gc_thread_data * thd);
int gc_is_mutator_active(gc_thread_data *thd); int gc_is_mutator_active(gc_thread_data *thd);
void gc_sleep_ms(int ms);
gc_heap *gc_heap_create(int heap_type, size_t size, size_t max_size, gc_heap *gc_heap_create(int heap_type, size_t size, size_t max_size,
size_t chunk_size, gc_thread_data *thd); size_t chunk_size, gc_thread_data *thd);
gc_heap *gc_heap_free(gc_heap *page, gc_heap *prev_page); gc_heap *gc_heap_free(gc_heap *page, gc_heap *prev_page);

View file

@ -120,7 +120,13 @@
"(void *data, int argc, closure _, object k, object thread_data_opaque)" "(void *data, int argc, closure _, object k, object thread_data_opaque)"
" gc_thread_data *td = (gc_thread_data *)(opaque_ptr(thread_data_opaque)); " gc_thread_data *td = (gc_thread_data *)(opaque_ptr(thread_data_opaque));
set_thread_blocked(data, k); set_thread_blocked(data, k);
pthread_join(td->thread_id, NULL); /* Cannot join to detached thread! pthread_join(td->thread_id, NULL);*/
while (1) {
if (!gc_is_mutator_active(td)){
break;
}
gc_sleep_ms(250);
}
return_thread_runnable(data, boolean_t);") return_thread_runnable(data, boolean_t);")
(define (thread-join! t) (define (thread-join! t)
(if (and (thread? t) (Cyc-opaque? (vector-ref t 2))) (if (and (thread? t) (Cyc-opaque? (vector-ref t 2)))