summaryrefslogtreecommitdiff
path: root/libguile/threads.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2013-11-22 13:01:53 +0100
committerAndy Wingo <wingo@pobox.com>2013-11-22 13:01:53 +0100
commit7af0c3b395fda906b5635323d28dd80482357aa7 (patch)
tree061632670083caf4419d5040b1542c473da003c9 /libguile/threads.c
parent9ebf79460736bbeaa75b1a86bfcd7ec23418c4ff (diff)
downloadguile-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.c39
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);
}