Properly store thread ID in thread objects

Also sketched out thread-join support but there are larger issues to consider to get that working.
This commit is contained in:
Justin Ethier 2017-01-22 18:58:37 -05:00
parent 1884f8ac52
commit 07500ce6d6
5 changed files with 45 additions and 9 deletions

View file

@ -24,3 +24,19 @@
(display "main thread done")
(newline)
(thread-sleep! 500)
;(display "thread join")
;(newline)
;(let ((t (make-thread
; (lambda ()
; (display "started second thread")
; (newline)
; (thread-sleep! 3000)
; (display "thread done")
; (newline)
; 1))))
; (thread-start! t)
; (thread-sleep! 1)
; (display (thread-join! t))
; (display "main thread done again")
; (newline))

View file

@ -140,6 +140,7 @@ struct gc_thread_data_t {
void **mark_buffer;
int mark_buffer_len;
pthread_mutex_t lock;
pthread_t thread_id;
// Data needed for call history
char **stack_traces;
int stack_trace_idx;

View file

@ -4167,6 +4167,7 @@ int gc_minor(void *data, object low_limit, object high_limit, closure cont,
// Transport exception stack
gc_move2heap(((gc_thread_data *) data)->exception_handler_stack);
gc_move2heap(((gc_thread_data *) data)->scm_thread_obj);
// Transport mutations
{
@ -4720,9 +4721,7 @@ void *Cyc_init_thread(object thread_and_thunk)
thd->gc_cont = cdr(thread_and_thunk);
thd->gc_num_args = 1;
thd->gc_args[0] = &Cyc_91end_91thread_67_primitive;
// thd->thread = pthread_self(); // TODO: ptr vs instance
// returns instance so would need to malloc here
// would also need to update termination code to free that memory
thd->thread_id = pthread_self();
gc_add_mutator(thd);
ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_NEW,
CYC_THREAD_STATE_RUNNABLE);

View file

@ -99,6 +99,7 @@
thd->gc_cont = &entry_pt;
thd->gc_args[0] = &clos_halt;
thd->gc_num_args = 1;
thd->thread_id = pthread_self();
gc_add_mutator(thd);
Cyc_heap_init(heap_size);
thd->thread_state = CYC_THREAD_STATE_RUNNABLE;

View file

@ -19,7 +19,7 @@
thread-yield!
thread-terminate!
current-thread
;; TODO: thread-join!
thread-join!
mutex?
make-mutex
@ -86,21 +86,40 @@
" gc_thread_data *td = (gc_thread_data *)data;
return_closcall1(data, k, td->scm_thread_obj); ")
(define-c %get-thread-data
"(void *data, int argc, closure _, object k)"
" gc_thread_data *td = (gc_thread_data *)data;
make_c_opaque(co, td);
return_closcall1(data, k, &co); ")
(define (thread-start! t)
;; Initiate a GC prior to running the thread, in case
;; t contains any closures on the "parent" thread's stack
(let* ((thunk (vector-ref t 1))
(thread-params (cons t thunk)))
(thread-params (cons t (lambda ()
(vector-set! t 2 (%get-thread-data))
(thunk)))))
(Cyc-minor-gc)
(let ((mutator-id (Cyc-spawn-thread! thread-params)))
(vector-set! t 2 mutator-id))))
(Cyc-spawn-thread! thread-params)
))
(define (thread-yield!) (thread-sleep! 1))
(define-c thread-terminate!
"(void *data, int argc, closure _, object k)"
" Cyc_end_thread(data); ")
;; TODO: thread-join!
;; TODO: possible to do this using mutator ID to get the pthread_t ??
;; TODO: not good enough, need to return value from thread
;; TODO: also not good enough because threads are started detached right now, which makes them unjoinable. need to reconcile that with the SRFI 18 requirement to have a join API
(define-c %thread-join!
"(void *data, int argc, closure _, object k, object thread_data_opaque)"
" gc_thread_data *td = (gc_thread_data *)(opaque_ptr(thread_data_opaque));
set_thread_blocked(data, k);
pthread_join(td->thread_id, NULL);
return_thread_runnable(data, boolean_t);")
(define (thread-join! t)
(if (and (thread? t) (Cyc-opaque? (vector-ref t 2)))
(%thread-join! (vector-ref t 2))
#f))
(define-c thread-sleep!
"(void *data, int argc, closure _, object k, object timeout)"