[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] GNU Guile branch, stable-2.0, updated. v2.0.0-127-g7f224
From: |
Andy Wingo |
Subject: |
[Guile-commits] GNU Guile branch, stable-2.0, updated. v2.0.0-127-g7f22442 |
Date: |
Fri, 25 Mar 2011 14:37:20 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".
http://git.savannah.gnu.org/cgit/guile.git/commit/?id=7f22442b2af85ea9db89c84fbd3acb6a96ee13fd
The branch, stable-2.0 has been updated
via 7f22442b2af85ea9db89c84fbd3acb6a96ee13fd (commit)
via 12c1d8616d8dfedcad65f34e3968f9544b629ae1 (commit)
via 2a6f90e52436afdbbcdcf99bfe8a5c24cefd9769 (commit)
from 5f0d2951a0a5179038bee55fe9af688f94738075 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 7f22442b2af85ea9db89c84fbd3acb6a96ee13fd
Author: Andy Wingo <address@hidden>
Date: Fri Mar 25 15:35:20 2011 +0100
avoid running GC when SCM_I_CURRENT_THREAD is unset
* libguile/threads.c (guilify_self_1): Prevent finalizers from running
before SCM_I_CURRENT_THREAD is set.
(do_thread_exit_trampoline): Leave the thread in the registered state.
(on_thread_exit): Always unregister the thread here.
commit 12c1d8616d8dfedcad65f34e3968f9544b629ae1
Author: Andy Wingo <address@hidden>
Date: Fri Mar 25 13:01:51 2011 +0100
threading / with_guile refactor to use more GC_stack_base
* libguile/init.h:
* libguile/init.c (scm_i_init_guile): Change arg to this internal
function from SCM_STACKITEM* to void*. Actually it's a
struct GC_stack_base*.
* libguile/bdw-gc.h: Don't do pthread redirects, because we don't want
to affect applications' pthread_* bindings.
* libguile/pthread-threads.h (scm_i_pthread_create)
(scm_i_pthread_detach, scm_i_pthread_exit, scm_i_pthread_cancel)
(scm_i_pthread_sigmask): Do pthread redirects here, in this internal
header.
* libguile/threads.h: Remove declaration of internal
scm_i_with_guile_and_parent. Remove declaration of undefined
scm_threads_init_first_thread. Make declaration of internal
scm_threads_prehistory actually internal, and take a void* (actually a
struct GC_stack_base*).
* libguile/threads.c (GC_get_stack_base): Implement a shim if this
function is unavailable, and fold in the implementations of
get_thread_stack_base.
(GC_call_with_stack_base): Actually implement.
(guilify_self_1): Take a GC_stack_base* as an arg.
(scm_i_init_thread_for_guile): Likewise, and set up libgc for
registration of other threads.
(scm_init_guile): Use GC_get_stack_base instead of our own guesswork.
(with_guile_and_parent, scm_i_with_guile_and_parent): Rework to
trampoline through a GC_call_with_stack_base.
(scm_threads_prehistory): Pass the "base" arg on to guilify_self_1.
commit 2a6f90e52436afdbbcdcf99bfe8a5c24cefd9769
Author: Andy Wingo <address@hidden>
Date: Fri Mar 25 10:47:10 2011 +0100
Revert "with-continuation-barrier carps, calls exit(3) _after_ unwinding"
This reverts commit ecba00af6501e082b86c8f2f7730081c733509d7.
-----------------------------------------------------------------------
Summary of changes:
libguile/bdw-gc.h | 7 +-
libguile/continuations.c | 16 +--
libguile/init.c | 8 +-
libguile/init.h | 4 +-
libguile/pthread-threads.h | 14 +-
libguile/threads.c | 385 +++++++++++++++++++----------------
libguile/threads.h | 8 +-
test-suite/tests/continuations.test | 13 +-
8 files changed, 227 insertions(+), 228 deletions(-)
diff --git a/libguile/bdw-gc.h b/libguile/bdw-gc.h
index 3adf99e..61c11eb 100644
--- a/libguile/bdw-gc.h
+++ b/libguile/bdw-gc.h
@@ -1,7 +1,7 @@
#ifndef SCM_BDW_GC_H
#define SCM_BDW_GC_H
-/* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2008, 2009, 2011 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -32,6 +32,11 @@
# define GC_THREADS 1
# define GC_REDIRECT_TO_LOCAL 1
+/* Don't #define pthread routines to their GC_pthread counterparts.
+ Instead we will be careful inside Guile to use the GC_pthread
+ routines. */
+# define GC_NO_THREAD_REDIRECTS 1
+
#endif
#include <gc/gc.h>
diff --git a/libguile/continuations.c b/libguile/continuations.c
index 28b6236..dc6850e 100644
--- a/libguile/continuations.c
+++ b/libguile/continuations.c
@@ -477,13 +477,7 @@ c_body (void *d)
static SCM
c_handler (void *d, SCM tag, SCM args)
{
- struct c_data *data;
-
- /* Print a message. Note that if TAG is `quit', this will exit() the
- process. */
- scm_handle_by_message_noexit (NULL, tag, args);
-
- data = (struct c_data *)d;
+ struct c_data *data = (struct c_data *)d;
data->result = NULL;
return SCM_UNSPECIFIED;
}
@@ -496,7 +490,7 @@ scm_c_with_continuation_barrier (void *(*func) (void *),
void *data)
c_data.data = data;
scm_i_with_continuation_barrier (c_body, &c_data,
c_handler, &c_data,
- NULL, NULL);
+ scm_handle_by_message_noexit, NULL);
return c_data.result;
}
@@ -514,10 +508,6 @@ scm_body (void *d)
static SCM
scm_handler (void *d, SCM tag, SCM args)
{
- /* Print a message. Note that if TAG is `quit', this will exit() the
- process. */
- scm_handle_by_message_noexit (NULL, tag, args);
-
return SCM_BOOL_F;
}
@@ -539,7 +529,7 @@ SCM_DEFINE (scm_with_continuation_barrier,
"with-continuation-barrier", 1,0,0,
scm_data.proc = proc;
return scm_i_with_continuation_barrier (scm_body, &scm_data,
scm_handler, &scm_data,
- NULL, NULL);
+ scm_handle_by_message_noexit, NULL);
}
#undef FUNC_NAME
diff --git a/libguile/init.c b/libguile/init.c
index d6a7105..8b3b8cd 100644
--- a/libguile/init.c
+++ b/libguile/init.c
@@ -376,17 +376,11 @@ cleanup_for_exit ()
}
void
-scm_i_init_guile (SCM_STACKITEM *base)
+scm_i_init_guile (void *base)
{
if (scm_initialized_p)
return;
- if (base == NULL)
- {
- fprintf (stderr, "cannot determine stack base!\n");
- abort ();
- }
-
if (sizeof (mpz_t) > (3 * sizeof (scm_t_bits)))
{
fprintf (stderr,
diff --git a/libguile/init.h b/libguile/init.h
index 7cfae76..bc6cddf 100644
--- a/libguile/init.h
+++ b/libguile/init.h
@@ -3,7 +3,7 @@
#ifndef SCM_INIT_H
#define SCM_INIT_H
-/* Copyright (C) 1995,1996,1997,2000, 2006, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1997,2000, 2006, 2008, 2011 Free Software
Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -38,7 +38,7 @@ SCM_API void scm_boot_guile (int argc, char **argv,
char **argv),
void *closure);
-SCM_INTERNAL void scm_i_init_guile (SCM_STACKITEM *base);
+SCM_INTERNAL void scm_i_init_guile (void *base);
SCM_API void scm_load_startup_files (void);
diff --git a/libguile/pthread-threads.h b/libguile/pthread-threads.h
index ca72f16..c180af2 100644
--- a/libguile/pthread-threads.h
+++ b/libguile/pthread-threads.h
@@ -3,7 +3,7 @@
#ifndef SCM_PTHREADS_THREADS_H
#define SCM_PTHREADS_THREADS_H
-/* Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2005, 2006, 2011 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -29,24 +29,24 @@
#include <pthread.h>
#include <sched.h>
-/* `libgc' intercepts pthread calls by defining wrapping macros. */
+/* `libgc' defines wrapper procedures for pthread calls. */
#include "libguile/bdw-gc.h"
/* Threads
*/
#define scm_i_pthread_t pthread_t
#define scm_i_pthread_self pthread_self
-#define scm_i_pthread_create pthread_create
-#define scm_i_pthread_detach pthread_detach
-#define scm_i_pthread_exit pthread_exit
-#define scm_i_pthread_cancel pthread_cancel
+#define scm_i_pthread_create GC_pthread_create
+#define scm_i_pthread_detach GC_pthread_detach
+#define scm_i_pthread_exit GC_pthread_exit
+#define scm_i_pthread_cancel GC_pthread_cancel
#define scm_i_pthread_cleanup_push pthread_cleanup_push
#define scm_i_pthread_cleanup_pop pthread_cleanup_pop
#define scm_i_sched_yield sched_yield
/* Signals
*/
-#define scm_i_pthread_sigmask pthread_sigmask
+#define scm_i_pthread_sigmask GC_pthread_sigmask
/* Mutexes
*/
diff --git a/libguile/threads.c b/libguile/threads.c
index 6f75dbe..ad5bbe1 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -89,7 +89,12 @@ typedef void * (* GC_fn_type) (void *);
/* Likewise struct GC_stack_base is missing before 7.1. */
#ifndef HAVE_GC_STACK_BASE
-struct GC_stack_base;
+struct GC_stack_base {
+ void * mem_base; /* Base of memory stack. */
+#ifdef __ia64__
+ void * reg_base; /* Base of separate register stack. */
+#endif
+};
static int
GC_register_my_thread (struct GC_stack_base *)
@@ -102,13 +107,93 @@ GC_unregister_my_thread ()
{
}
+#if !SCM_USE_PTHREAD_THREADS
+/* No threads; we can just use GC_stackbottom. */
static void *
-GC_call_with_stack_base(void * (*fn) (struct GC_stack_base*, void*), void *arg)
+get_thread_stack_base ()
+{
+ return GC_stackbottom;
+}
+
+#elif defined HAVE_PTHREAD_ATTR_GETSTACK && defined HAVE_PTHREAD_GETATTR_NP \
+ && defined PTHREAD_ATTR_GETSTACK_WORKS
+/* This method for GNU/Linux and perhaps some other systems.
+ It's not for MacOS X or Solaris 10, since pthread_getattr_np is not
+ available on them. */
+static void *
+get_thread_stack_base ()
+{
+ pthread_attr_t attr;
+ void *start, *end;
+ size_t size;
+
+ pthread_getattr_np (pthread_self (), &attr);
+ pthread_attr_getstack (&attr, &start, &size);
+ end = (char *)start + size;
+
+#if SCM_STACK_GROWS_UP
+ return start;
+#else
+ return end;
+#endif
+}
+
+#elif defined HAVE_PTHREAD_GET_STACKADDR_NP
+/* This method for MacOS X.
+ It'd be nice if there was some documentation on pthread_get_stackaddr_np,
+ but as of 2006 there's nothing obvious at apple.com. */
+static void *
+get_thread_stack_base ()
{
- return fn (NULL, arg);
+ return pthread_get_stackaddr_np (pthread_self ());
+}
+
+#else
+#error Threads enabled with old BDW-GC, but missing get_thread_stack_base
impl. Please upgrade to libgc >= 7.1.
+#endif
+
+static int
+GC_get_stack_base (struct GC_stack_base *)
+{
+ stack_base->mem_base = get_thread_stack_base ();
+#ifdef __ia64__
+ /* Calculate and store off the base of this thread's register
+ backing store (RBS). Unfortunately our implementation(s) of
+ scm_ia64_register_backing_store_base are only reliable for the
+ main thread. For other threads, therefore, find out the current
+ top of the RBS, and use that as a maximum. */
+ stack_base->reg_base = scm_ia64_register_backing_store_base ();
+ {
+ ucontext_t ctx;
+ void *bsp;
+ getcontext (&ctx);
+ bsp = scm_ia64_ar_bsp (&ctx);
+ if (stack_base->reg_base > bsp)
+ stack_base->reg_base = bsp;
+ }
+#endif
+ return GC_SUCCESS;
}
+
+static void *
+GC_call_with_stack_base(void * (*fn) (struct GC_stack_base*, void*), void *arg)
+{
+ struct GC_stack_base stack_base;
+
+ stack_base.mem_base = (void*)&stack_base;
+#ifdef __ia64__
+ /* FIXME: Untested. */
+ {
+ ucontext_t ctx;
+ getcontext (&ctx);
+ stack_base.reg_base = scm_ia64_ar_bsp (&ctx);
+ }
#endif
+ return fn (&stack_base, arg);
+}
+#endif /* HAVE_GC_STACK_BASE */
+
/* Now define with_gc_active and with_gc_inactive. */
@@ -401,72 +486,75 @@ static SCM scm_i_default_dynamic_state;
/* Perform first stage of thread initialisation, in non-guile mode.
*/
static void
-guilify_self_1 (SCM_STACKITEM *base)
-{
- scm_i_thread *t = scm_gc_malloc (sizeof (scm_i_thread), "thread");
-
- t->pthread = scm_i_pthread_self ();
- t->handle = SCM_BOOL_F;
- t->result = SCM_BOOL_F;
- t->cleanup_handler = SCM_BOOL_F;
- t->mutexes = SCM_EOL;
- t->held_mutex = NULL;
- t->join_queue = SCM_EOL;
- t->dynamic_state = SCM_BOOL_F;
- t->dynwinds = SCM_EOL;
- t->active_asyncs = SCM_EOL;
- t->block_asyncs = 1;
- t->pending_asyncs = 1;
- t->critical_section_level = 0;
- t->base = base;
+guilify_self_1 (struct GC_stack_base *base)
+{
+ scm_i_thread t;
+
+ /* We must arrange for SCM_I_CURRENT_THREAD to point to a valid value
+ before allocating anything in this thread, because allocation could
+ cause GC to run, and GC could cause finalizers, which could invoke
+ Scheme functions, which need the current thread to be set. */
+
+ t.pthread = scm_i_pthread_self ();
+ t.handle = SCM_BOOL_F;
+ t.result = SCM_BOOL_F;
+ t.cleanup_handler = SCM_BOOL_F;
+ t.mutexes = SCM_EOL;
+ t.held_mutex = NULL;
+ t.join_queue = SCM_EOL;
+ t.dynamic_state = SCM_BOOL_F;
+ t.dynwinds = SCM_EOL;
+ t.active_asyncs = SCM_EOL;
+ t.block_asyncs = 1;
+ t.pending_asyncs = 1;
+ t.critical_section_level = 0;
+ t.base = base->mem_base;
#ifdef __ia64__
- /* Calculate and store off the base of this thread's register
- backing store (RBS). Unfortunately our implementation(s) of
- scm_ia64_register_backing_store_base are only reliable for the
- main thread. For other threads, therefore, find out the current
- top of the RBS, and use that as a maximum. */
- t->register_backing_store_base = scm_ia64_register_backing_store_base ();
- {
- ucontext_t ctx;
- void *bsp;
- getcontext (&ctx);
- bsp = scm_ia64_ar_bsp (&ctx);
- if (t->register_backing_store_base > bsp)
- t->register_backing_store_base = bsp;
- }
+ t.register_backing_store_base = base->reg-base;
#endif
- t->continuation_root = SCM_EOL;
- t->continuation_base = base;
- scm_i_pthread_cond_init (&t->sleep_cond, NULL);
- t->sleep_mutex = NULL;
- t->sleep_object = SCM_BOOL_F;
- t->sleep_fd = -1;
-
- if (pipe (t->sleep_pipe) != 0)
+ t.continuation_root = SCM_EOL;
+ t.continuation_base = t.base;
+ scm_i_pthread_cond_init (&t.sleep_cond, NULL);
+ t.sleep_mutex = NULL;
+ t.sleep_object = SCM_BOOL_F;
+ t.sleep_fd = -1;
+
+ if (pipe (t.sleep_pipe) != 0)
/* FIXME: Error conditions during the initialization phase are handled
gracelessly since public functions such as `scm_init_guile ()'
currently have type `void'. */
abort ();
- scm_i_pthread_mutex_init (&t->admin_mutex, NULL);
- t->current_mark_stack_ptr = NULL;
- t->current_mark_stack_limit = NULL;
- t->canceled = 0;
- t->exited = 0;
- t->guile_mode = 0;
+ scm_i_pthread_mutex_init (&t.admin_mutex, NULL);
+ t.current_mark_stack_ptr = NULL;
+ t.current_mark_stack_limit = NULL;
+ t.canceled = 0;
+ t.exited = 0;
+ t.guile_mode = 0;
- scm_i_pthread_setspecific (scm_i_thread_key, t);
+ /* The switcheroo. */
+ {
+ scm_i_thread *t_ptr = &t;
+
+ GC_disable ();
+ t_ptr = GC_malloc (sizeof (scm_i_thread));
+ memcpy (t_ptr, &t, sizeof t);
+
+ scm_i_pthread_setspecific (scm_i_thread_key, t_ptr);
#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
- /* Cache the current thread in TLS for faster lookup. */
- scm_i_current_thread = t;
+ /* Cache the current thread in TLS for faster lookup. */
+ scm_i_current_thread = t_ptr;
#endif
- scm_i_pthread_mutex_lock (&thread_admin_mutex);
- t->next_thread = all_threads;
- all_threads = t;
- thread_count++;
- scm_i_pthread_mutex_unlock (&thread_admin_mutex);
+ scm_i_pthread_mutex_lock (&thread_admin_mutex);
+ t_ptr->next_thread = all_threads;
+ all_threads = t_ptr;
+ thread_count++;
+ scm_i_pthread_mutex_unlock (&thread_admin_mutex);
+
+ GC_enable ();
+ }
}
/* Perform second stage of thread initialisation, in guile mode.
@@ -572,17 +660,10 @@ do_thread_exit (void *v)
static void *
do_thread_exit_trampoline (struct GC_stack_base *sb, void *v)
{
- void *ret;
- int registered;
+ /* Won't hurt if we are already registered. */
+ GC_register_my_thread (sb);
- registered = GC_register_my_thread (sb);
-
- ret = scm_with_guile (do_thread_exit, v);
-
- if (registered == GC_SUCCESS)
- GC_unregister_my_thread ();
-
- return ret;
+ return scm_with_guile (do_thread_exit, v);
}
static void
@@ -608,11 +689,9 @@ on_thread_exit (void *v)
shutting it down. */
scm_i_ensure_signal_delivery_thread ();
- /* Unblocking the joining threads needs to happen in guile mode
- since the queue is a SCM data structure. Trampoline through
- GC_call_with_stack_base so that the GC works even if it already
- cleaned up for this thread. */
- GC_call_with_stack_base (do_thread_exit_trampoline, v);
+ /* Scheme-level thread finalizers and other cleanup needs to happen in
+ guile mode. */
+ GC_call_with_stack_base (do_thread_exit_trampoline, t);
/* Removing ourself from the list of all threads needs to happen in
non-guile mode since all SCM values on our stack become
@@ -640,6 +719,8 @@ on_thread_exit (void *v)
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
scm_i_pthread_setspecific (scm_i_thread_key, NULL);
+
+ GC_unregister_my_thread ();
}
static scm_i_pthread_once_t init_thread_key_once = SCM_I_PTHREAD_ONCE_INIT;
@@ -668,7 +749,7 @@ init_thread_key (void)
be sure. New threads are put into guile mode implicitly. */
static int
-scm_i_init_thread_for_guile (SCM_STACKITEM *base, SCM parent)
+scm_i_init_thread_for_guile (struct GC_stack_base *base, SCM parent)
{
scm_i_pthread_once (&init_thread_key_once, init_thread_key);
@@ -690,6 +771,10 @@ scm_i_init_thread_for_guile (SCM_STACKITEM *base, SCM
parent)
initialization.
*/
scm_i_init_guile (base);
+
+ /* Allow other threads to come in later. */
+ GC_allow_register_threads ();
+
scm_i_pthread_mutex_unlock (&scm_i_init_mutex);
}
else
@@ -698,6 +783,10 @@ scm_i_init_thread_for_guile (SCM_STACKITEM *base, SCM
parent)
the first time. Only initialize this thread.
*/
scm_i_pthread_mutex_unlock (&scm_i_init_mutex);
+
+ /* Register this thread with libgc. */
+ GC_register_my_thread (base);
+
guilify_self_1 (base);
guilify_self_2 (parent);
}
@@ -705,135 +794,58 @@ scm_i_init_thread_for_guile (SCM_STACKITEM *base, SCM
parent)
}
}
-#if SCM_USE_PTHREAD_THREADS
-
-#if defined HAVE_PTHREAD_ATTR_GETSTACK && defined HAVE_PTHREAD_GETATTR_NP
-/* This method for GNU/Linux and perhaps some other systems.
- It's not for MacOS X or Solaris 10, since pthread_getattr_np is not
- available on them. */
-#define HAVE_GET_THREAD_STACK_BASE
-
-static SCM_STACKITEM *
-get_thread_stack_base ()
+void
+scm_init_guile ()
{
- pthread_attr_t attr;
- void *start, *end;
- size_t size;
-
- pthread_getattr_np (pthread_self (), &attr);
- pthread_attr_getstack (&attr, &start, &size);
- end = (char *)start + size;
-
- /* XXX - pthread_getattr_np from LinuxThreads does not seem to work
- for the main thread, but we can use scm_get_stack_base in that
- case.
- */
-
-#ifndef PTHREAD_ATTR_GETSTACK_WORKS
- if ((void *)&attr < start || (void *)&attr >= end)
- return (SCM_STACKITEM *) GC_stackbottom;
+ struct GC_stack_base stack_base;
+
+ if (GC_get_stack_base (&stack_base) == GC_SUCCESS)
+ scm_i_init_thread_for_guile (&stack_base,
+ scm_i_default_dynamic_state);
else
-#endif
{
-#if SCM_STACK_GROWS_UP
- return start;
-#else
- return end;
-#endif
+ fprintf (stderr, "Failed to get stack base for current thread.\n");
+ exit (1);
}
}
-#elif defined HAVE_PTHREAD_GET_STACKADDR_NP
-/* This method for MacOS X.
- It'd be nice if there was some documentation on pthread_get_stackaddr_np,
- but as of 2006 there's nothing obvious at apple.com. */
-#define HAVE_GET_THREAD_STACK_BASE
-static SCM_STACKITEM *
-get_thread_stack_base ()
-{
- return pthread_get_stackaddr_np (pthread_self ());
-}
-
-#elif defined (__MINGW32__)
-/* This method for mingw. In mingw the basic scm_get_stack_base can be used
- in any thread. We don't like hard-coding the name of a system, but there
- doesn't seem to be a cleaner way of knowing scm_get_stack_base can
- work. */
-#define HAVE_GET_THREAD_STACK_BASE
-static SCM_STACKITEM *
-get_thread_stack_base ()
-{
- return (SCM_STACKITEM *) GC_stackbottom;
-}
-
-#endif /* pthread methods of get_thread_stack_base */
-
-#else /* !SCM_USE_PTHREAD_THREADS */
-
-#define HAVE_GET_THREAD_STACK_BASE
-
-static SCM_STACKITEM *
-get_thread_stack_base ()
-{
- return (SCM_STACKITEM *) GC_stackbottom;
-}
-
-#endif /* !SCM_USE_PTHREAD_THREADS */
-
-#ifdef HAVE_GET_THREAD_STACK_BASE
-
-void
-scm_init_guile ()
-{
- scm_i_init_thread_for_guile (get_thread_stack_base (),
- scm_i_default_dynamic_state);
-}
-
-#endif
-
-void *
-scm_with_guile (void *(*func)(void *), void *data)
-{
- return scm_i_with_guile_and_parent (func, data,
- scm_i_default_dynamic_state);
-}
-
SCM_UNUSED static void
scm_leave_guile_cleanup (void *x)
{
on_thread_exit (SCM_I_CURRENT_THREAD);
}
-struct with_guile_trampoline_args
+struct with_guile_args
{
GC_fn_type func;
void *data;
+ SCM parent;
};
static void *
with_guile_trampoline (void *data)
{
- struct with_guile_trampoline_args *args = data;
+ struct with_guile_args *args = data;
return scm_c_with_continuation_barrier (args->func, args->data);
}
-void *
-scm_i_with_guile_and_parent (void *(*func)(void *), void *data, SCM parent)
+static void *
+with_guile_and_parent (struct GC_stack_base *base, void *data)
{
void *res;
int new_thread;
scm_i_thread *t;
- SCM_STACKITEM base_item;
+ struct with_guile_args *args = data;
- new_thread = scm_i_init_thread_for_guile (&base_item, parent);
+ new_thread = scm_i_init_thread_for_guile (base, args->parent);
t = SCM_I_CURRENT_THREAD;
if (new_thread)
{
/* We are in Guile mode. */
assert (t->guile_mode);
- res = scm_c_with_continuation_barrier (func, data);
+ res = scm_c_with_continuation_barrier (args->func, args->data);
/* Leave Guile mode. */
t->guile_mode = 0;
@@ -841,14 +853,10 @@ scm_i_with_guile_and_parent (void *(*func)(void *), void
*data, SCM parent)
else if (t->guile_mode)
{
/* Already in Guile mode. */
- res = scm_c_with_continuation_barrier (func, data);
+ res = scm_c_with_continuation_barrier (args->func, args->data);
}
else
{
- struct with_guile_trampoline_args args;
- args.func = func;
- args.data = data;
-
/* We are not in Guile mode, either because we are not within a
scm_with_guile, or because we are within a scm_without_guile.
@@ -857,20 +865,39 @@ scm_i_with_guile_and_parent (void *(*func)(void *), void
*data, SCM parent)
when this thread was first guilified. Thus, `base' must be
updated. */
#if SCM_STACK_GROWS_UP
- if (SCM_STACK_PTR (&base_item) < t->base)
- t->base = SCM_STACK_PTR (&base_item);
+ if (SCM_STACK_PTR (base->mem_base) < t->base)
+ t->base = SCM_STACK_PTR (base->mem_base);
#else
- if (SCM_STACK_PTR (&base_item) > t->base)
- t->base = SCM_STACK_PTR (&base_item);
+ if (SCM_STACK_PTR (base->mem_base) > t->base)
+ t->base = SCM_STACK_PTR (base->mem_base);
#endif
t->guile_mode = 1;
- res = with_gc_active (with_guile_trampoline, &args);
+ res = with_gc_active (with_guile_trampoline, args);
t->guile_mode = 0;
}
return res;
}
+static void *
+scm_i_with_guile_and_parent (void *(*func)(void *), void *data, SCM parent)
+{
+ struct with_guile_args args;
+
+ args.func = func;
+ args.data = data;
+ args.parent = parent;
+
+ return GC_call_with_stack_base (with_guile_and_parent, &args);
+}
+
+void *
+scm_with_guile (void *(*func)(void *), void *data)
+{
+ return scm_i_with_guile_and_parent (func, data,
+ scm_i_default_dynamic_state);
+}
+
void *
scm_without_guile (void *(*func)(void *), void *data)
{
@@ -2003,7 +2030,7 @@ pthread_mutexattr_t scm_i_pthread_mutexattr_recursive[1];
#endif
void
-scm_threads_prehistory (SCM_STACKITEM *base)
+scm_threads_prehistory (void *base)
{
#if SCM_USE_PTHREAD_THREADS
pthread_mutexattr_init (scm_i_pthread_mutexattr_recursive);
@@ -2016,7 +2043,7 @@ scm_threads_prehistory (SCM_STACKITEM *base)
scm_i_pthread_mutex_init (&scm_i_misc_mutex, NULL);
scm_i_pthread_cond_init (&wake_up_cond, NULL);
- guilify_self_1 (base);
+ guilify_self_1 ((struct GC_stack_base *) base);
}
scm_t_bits scm_tc16_thread;
diff --git a/libguile/threads.h b/libguile/threads.h
index 475af32..9e44684 100644
--- a/libguile/threads.h
+++ b/libguile/threads.h
@@ -136,13 +136,7 @@ SCM_API SCM scm_spawn_thread (scm_t_catch_body body, void
*body_data,
SCM_API void *scm_without_guile (void *(*func)(void *), void *data);
SCM_API void *scm_with_guile (void *(*func)(void *), void *data);
-SCM_INTERNAL void *scm_i_with_guile_and_parent (void *(*func)(void *),
- void *data, SCM parent);
-
-
-void scm_threads_prehistory (SCM_STACKITEM *);
-void scm_threads_init_first_thread (void);
-
+SCM_INTERNAL void scm_threads_prehistory (void *);
SCM_INTERNAL void scm_init_threads (void);
SCM_INTERNAL void scm_init_thread_procs (void);
SCM_INTERNAL void scm_init_threads_default_dynamic_state (void);
diff --git a/test-suite/tests/continuations.test
b/test-suite/tests/continuations.test
index a436b90..f6db40e 100644
--- a/test-suite/tests/continuations.test
+++ b/test-suite/tests/continuations.test
@@ -1,7 +1,7 @@
;;;; -*- scheme -*-
;;;; continuations.test --- test suite for continutations
;;;;
-;;;; Copyright (C) 2003, 2006, 2009, 2011 Free Software Foundation, Inc.
+;;;; Copyright (C) 2003, 2006, 2009 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
@@ -80,17 +80,6 @@
(error "Catch me if you can!")))))))))
handled))
- (pass-if "exit unwinds dynwinds inside a continuation barrier"
- (let ((s (with-error-to-string
- (lambda ()
- (with-continuation-barrier
- (lambda ()
- (dynamic-wind
- (lambda () #f)
- (lambda () (exit 1))
- (lambda () (throw 'abcde)))))))))
- (and (string-contains s "abcde") #t)))
-
(with-debugging-evaluator
(pass-if "make a stack from a continuation"
hooks/post-receive
--
GNU Guile
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Guile-commits] GNU Guile branch, stable-2.0, updated. v2.0.0-127-g7f22442,
Andy Wingo <=