guile-commits
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]