diff options
author | Andy Wingo <wingo@pobox.com> | 2013-11-22 13:01:53 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2013-11-22 13:01:53 +0100 |
commit | 7af0c3b395fda906b5635323d28dd80482357aa7 (patch) | |
tree | 061632670083caf4419d5040b1542c473da003c9 /libguile/threads.c | |
parent | 9ebf79460736bbeaa75b1a86bfcd7ec23418c4ff (diff) | |
download | guile-7af0c3b395fda906b5635323d28dd80482357aa7.tar.gz |
Add thread mark procedure
* libguile/threads.c (thread_mark): A mark procedure for threads.
Eventually will mark the stack.
(guilify_self_1): Move initialization of VP earlier. Allocate thread
using thread_gc_kind.
(scm_threads_prehistory): Initialize thread_gc_kind.
Diffstat (limited to 'libguile/threads.c')
-rw-r--r-- | libguile/threads.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/libguile/threads.c b/libguile/threads.c index a313b8b7a..3f30ed5c2 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -25,6 +25,7 @@ #endif #include "libguile/bdw-gc.h" +#include <gc/gc_mark.h> #include "libguile/_scm.h" #include <stdlib.h> @@ -70,6 +71,34 @@ + +/* The GC "kind" for threads that allow them to mark their VM + stacks. */ +static int thread_gc_kind; + +static struct GC_ms_entry * +thread_mark (GC_word *addr, struct GC_ms_entry *mark_stack_ptr, + struct GC_ms_entry *mark_stack_limit, GC_word env) +{ + int word; + const struct scm_i_thread *t = (struct scm_i_thread *) addr; + + if (SCM_UNPACK (t->handle) == 0) + /* T must be on the free-list; ignore. (See warning in + gc_mark.h.) */ + return mark_stack_ptr; + + /* Mark T. We could be more precise, but it doesn't matte. */ + for (word = 0; word * sizeof (*addr) < sizeof (*t); word++) + mark_stack_ptr = GC_MARK_AND_PUSH ((void *) addr[word], + mark_stack_ptr, mark_stack_limit, + NULL); + + return mark_stack_ptr; +} + + + static void to_timespec (SCM t, scm_t_timespec *waittime) { @@ -88,6 +117,7 @@ to_timespec (SCM t, scm_t_timespec *waittime) } } + /*** Queues */ @@ -372,6 +402,7 @@ guilify_self_1 (struct GC_stack_base *base) t.sleep_mutex = NULL; t.sleep_object = SCM_BOOL_F; t.sleep_fd = -1; + t.vp = NULL; if (pipe2 (t.sleep_pipe, O_CLOEXEC) != 0) /* FIXME: Error conditions during the initialization phase are handled @@ -389,7 +420,7 @@ guilify_self_1 (struct GC_stack_base *base) scm_i_thread *t_ptr = &t; GC_disable (); - t_ptr = GC_malloc (sizeof (scm_i_thread)); + t_ptr = GC_generic_malloc (sizeof (*t_ptr), thread_gc_kind); memcpy (t_ptr, &t, sizeof t); scm_i_pthread_setspecific (scm_i_thread_key, t_ptr); @@ -422,7 +453,6 @@ guilify_self_2 (SCM parent) t->continuation_root = scm_cons (t->handle, SCM_EOL); t->continuation_base = t->base; - t->vp = NULL; if (scm_is_true (parent)) t->dynamic_state = scm_make_dynamic_state (parent); @@ -1997,6 +2027,11 @@ scm_threads_prehistory (void *base) scm_i_pthread_mutex_init (&scm_i_misc_mutex, NULL); scm_i_pthread_cond_init (&wake_up_cond, NULL); + thread_gc_kind = + GC_new_kind (GC_new_free_list (), + GC_MAKE_PROC (GC_new_proc (thread_mark), 0), + 0, 1); + guilify_self_1 ((struct GC_stack_base *) base); } |