]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix a problem with the garbage collector, storing the stack top every
authorGiuseppe Scrivano <gscrivano@gnu.org>
Mon, 21 Sep 2009 12:51:27 +0000 (14:51 +0200)
committerGiuseppe Scrivano <gscrivano@gnu.org>
Mon, 21 Sep 2009 12:51:27 +0000 (14:51 +0200)
time the running thread is blocked.

src/thread.c

index 036823d52ec334c2c71732c8f0a4fb4cce41c9dd..41a65bdde84808e4b89ac4024896f3ea254723ed 100644 (file)
@@ -74,6 +74,26 @@ thread_schedule ()
     }
 }
 
+/* Schedule a new thread and block the caller until it is not scheduled
+   again.  */
+static inline void
+reschedule_and_wait (char *end)
+{
+  current_thread->stack_top = end;
+  if (!thread_inhibit_yield_p ())
+    thread_schedule ();
+
+  if (next_thread != current_thread->pthread_id)
+    pthread_cond_broadcast (&buffer_cond);
+
+  pthread_mutex_unlock (&global_lock);
+
+  pthread_mutex_lock (&global_lock);
+
+  while (current_thread->pthread_id != next_thread)
+    pthread_cond_wait (&buffer_cond, &global_lock);
+}
+
 static void
 mark_one_thread (struct thread_state *thread)
 {
@@ -161,14 +181,7 @@ thread_acquire_buffer (char *end, void *nb)
       current_buffer->prev_owner = Qnil;
     }
 
-  if (!thread_inhibit_yield_p ())
-    thread_schedule ();
-
-  if (next_thread != current_thread->pthread_id)
-    pthread_cond_broadcast (&buffer_cond);
-
-  while (current_thread->pthread_id != next_thread)
-    pthread_cond_wait (&buffer_cond, &global_lock);
+  reschedule_and_wait (end);
 
   /* FIXME: if buffer is killed */
   new_buffer->prev_owner = new_buffer->owner;
@@ -187,21 +200,7 @@ thread_inhibit_yield_p  ()
 static void
 thread_yield_callback (char *end, void *ignore)
 {
-  if (thread_inhibit_yield_p ())
-    return;
-
-  current_thread->stack_top = end;
-  thread_schedule ();
-
-  if (next_thread != current_thread->pthread_id)
-    pthread_cond_broadcast (&buffer_cond);
-
-  pthread_mutex_unlock (&global_lock);
-
-  pthread_mutex_lock (&global_lock);
-
-  while (next_thread != current_thread->pthread_id)
-    pthread_cond_wait (&buffer_cond, &global_lock);
+  reschedule_and_wait (end);
 }
 
 void