mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-19 05:39:17 +02:00
Issue #320 - Track threads that have not yet run
This allows (thread-join!) to be able to wait on these new threads
This commit is contained in:
parent
c49c753f9d
commit
d1dbd7fae9
4 changed files with 62 additions and 6 deletions
50
gc.c
50
gc.c
|
@ -66,8 +66,11 @@ static int mark_stack_i = 0;
|
|||
// thread terminates (normally or not).
|
||||
static gc_thread_data *primordial_thread = NULL;
|
||||
|
||||
/** Data new mutator threads that are not running yet */
|
||||
static ck_array_t new_mutators;
|
||||
/** Data for each individual mutator thread */
|
||||
ck_array_t Cyc_mutators, old_mutators;
|
||||
static ck_array_t Cyc_mutators;
|
||||
static ck_array_t old_mutators;
|
||||
static pthread_mutex_t mutators_lock;
|
||||
|
||||
static void my_free(void *p, size_t m, bool d)
|
||||
|
@ -214,6 +217,10 @@ void gc_initialize(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (ck_array_init(&new_mutators, CK_ARRAY_MODE_SPMC, &my_allocator, 10) == 0) {
|
||||
fprintf(stderr, "Unable to initialize mutator array\n");
|
||||
exit(1);
|
||||
}
|
||||
if (ck_array_init(&old_mutators, CK_ARRAY_MODE_SPMC, &my_allocator, 10) == 0) {
|
||||
fprintf(stderr, "Unable to initialize mutator array\n");
|
||||
exit(1);
|
||||
|
@ -230,7 +237,25 @@ void gc_initialize(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Add data for a new mutator
|
||||
* @brief Add data for a new mutator that is not yet scheduled to run.
|
||||
* This is done so there is a record in the system even if the
|
||||
* thread is not running, to prevent race conditions for any
|
||||
* functions (EG: thread-join!) that need to access the thread.
|
||||
* @param thd Thread data for the mutator
|
||||
*/
|
||||
void gc_add_new_unrunning_mutator(gc_thread_data * thd)
|
||||
{
|
||||
pthread_mutex_lock(&mutators_lock);
|
||||
if (ck_array_put_unique(&new_mutators, (void *)thd) < 0) {
|
||||
fprintf(stderr, "Unable to allocate memory for a new thread, exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
ck_array_commit(&new_mutators);
|
||||
pthread_mutex_unlock(&mutators_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add data for a new mutator that is starting to run.
|
||||
* @param thd Thread data for the mutator
|
||||
*/
|
||||
void gc_add_mutator(gc_thread_data * thd)
|
||||
|
@ -246,6 +271,10 @@ void gc_add_mutator(gc_thread_data * thd)
|
|||
// Main thread is always the first one added
|
||||
if (primordial_thread == NULL) {
|
||||
primordial_thread = thd;
|
||||
} else {
|
||||
// At this point the mutator is running, so remove it from the new list
|
||||
ck_array_remove(&new_mutators, (void *)thd);
|
||||
ck_array_commit(&new_mutators);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,6 +319,23 @@ int gc_is_mutator_active(gc_thread_data *thd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine if the given mutator is in the list of new threads.
|
||||
* @param thd Thread data object of the m
|
||||
* @return A true value if the mutator is found, 0 otherwise.
|
||||
*/
|
||||
int gc_is_mutator_new(gc_thread_data *thd)
|
||||
{
|
||||
ck_array_iterator_t iterator;
|
||||
gc_thread_data *m;
|
||||
CK_ARRAY_FOREACH(&new_mutators, &iterator, &m) {
|
||||
if (m == thd) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free thread data for all terminated mutators
|
||||
*/
|
||||
|
|
|
@ -349,9 +349,11 @@ struct gc_thread_data_t {
|
|||
|
||||
/* GC prototypes */
|
||||
void gc_initialize(void);
|
||||
void gc_add_new_unrunning_mutator(gc_thread_data * thd);
|
||||
void gc_add_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_new(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,
|
||||
size_t chunk_size, gc_thread_data *thd);
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
(thread-start! t2)
|
||||
|
||||
(write (thread? t))
|
||||
(thread-sleep! 1)
|
||||
(write (thread? t2))
|
||||
(newline)
|
||||
;; Main thread - wait for thread to broadcast it is done
|
||||
(thread-join! t)
|
||||
(thread-join! t2)
|
||||
|
|
13
srfi/18.sld
13
srfi/18.sld
|
@ -71,7 +71,13 @@
|
|||
;; - name
|
||||
;; - specific
|
||||
;; - internal
|
||||
(vector 'cyc-thread-obj thunk #f name-str #f #f)))
|
||||
(vector
|
||||
'cyc-thread-obj
|
||||
thunk
|
||||
(%alloc-thread-data) ;; Internal data for new thread
|
||||
name-str
|
||||
#f
|
||||
#f)))
|
||||
|
||||
(define (thread-name t) (vector-ref t 3))
|
||||
(define (thread-specific t) (vector-ref t 4))
|
||||
|
@ -100,6 +106,7 @@
|
|||
(define-c %alloc-thread-data
|
||||
"(void *data, int argc, closure _, object k)"
|
||||
" gc_thread_data *td = malloc(sizeof(gc_thread_data));
|
||||
gc_add_new_unrunning_mutator(td); /* Register this thread */
|
||||
make_c_opaque(co, td);
|
||||
return_closcall1(data, k, &co); ")
|
||||
|
||||
|
@ -112,7 +119,6 @@
|
|||
(thunk)))))
|
||||
(vector-set! t 5 (%get-thread-data)) ;; Temporarily make parent thread
|
||||
;; data available for child init
|
||||
(vector-set! t 2 (%alloc-thread-data)) ;; Data for new thread
|
||||
(Cyc-minor-gc)
|
||||
(Cyc-spawn-thread! thread-params)
|
||||
))
|
||||
|
@ -131,7 +137,8 @@
|
|||
set_thread_blocked(data, k);
|
||||
/* Cannot join to detached thread! pthread_join(td->thread_id, NULL);*/
|
||||
while (1) {
|
||||
if (!gc_is_mutator_active(td)){
|
||||
if (!gc_is_mutator_new(td) &&
|
||||
!gc_is_mutator_active(td)){
|
||||
break;
|
||||
}
|
||||
gc_sleep_ms(250);
|
||||
|
|
Loading…
Add table
Reference in a new issue