From ced0df2779d0faa03be17cf3d25a64b7eb55c73b Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sat, 19 Sep 2009 16:09:32 +0200 Subject: [PATCH] Move all locking logic into thread.c. --- src/buffer.c | 56 +------------------------------------------------------- src/buffer.h | 1 - src/thread.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- src/thread.h | 2 ++ 4 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 60c63fecdff..05d498e19c7 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -107,10 +107,6 @@ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; int last_per_buffer_idx; -/* condition var .. w/ global lock */ - -static pthread_cond_t buffer_cond; - EXFUN (Fset_buffer, 1); void set_buffer_internal P_ ((struct buffer *b)); void set_buffer_internal_1 P_ ((struct buffer *b)); @@ -1866,43 +1862,6 @@ set_buffer_internal (b) set_buffer_internal_1 (b); } -static void -acquire_buffer (char *end, void *nb) -{ - struct buffer *new_buffer = nb; - - /* FIXME this check should be in the caller, for better - single-threaded performance. */ - if (other_threads_p () && !thread_inhibit_yield_p ()) - { - /* Let other threads try to acquire a buffer. */ - pthread_cond_broadcast (&buffer_cond); - - /* If our desired buffer is locked, wait for it. */ - while (other_threads_p () - && !current_thread->nolock - && !EQ (new_buffer->owner, Qnil) - /* We set the owner to Qt to mean it is being killed. */ - && !EQ (new_buffer->owner, Qt)) - pthread_cond_wait (&buffer_cond, &global_lock); - } -} - -/* Mark the thread's current buffer as not having an owner. This is - only ok to call when the thread is shutting down. The global lock - must be held when calling this function. */ - -void -release_buffer (thread) - struct thread_state *thread; -{ - if (!EQ (thread->m_current_buffer->owner, Qt)) - { - thread->m_current_buffer->owner = Qnil; - pthread_cond_broadcast (&buffer_cond); - } -} - /* Set the current buffer to B, and do not set windows_or_buffers_changed. This is used by redisplay. */ @@ -1923,18 +1882,7 @@ set_buffer_internal_1 (b) return; old_buf = current_buffer; - if (current_buffer) - { - current_buffer->owner = current_buffer->prev_owner; - current_buffer->prev_owner = Qnil; - } - flush_stack_call_func (acquire_buffer, b); - /* FIXME: if buffer is killed */ - b->prev_owner = b->owner; - if (current_thread->nolock) - b->owner = Qnil; - else - b->owner = get_current_thread (); + flush_stack_call_func (thread_acquire_buffer, b); current_buffer = b; last_known_column_point = -1; /* invalidate indentation cache */ @@ -5413,8 +5361,6 @@ init_buffer () Lisp_Object temp; int len; - pthread_cond_init (&buffer_cond, NULL); - #ifdef USE_MMAP_FOR_BUFFERS { /* When using the ralloc implementation based on mmap(2), buffer diff --git a/src/buffer.h b/src/buffer.h index d68aca19b21..cd9361a864f 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -857,7 +857,6 @@ extern void record_buffer P_ ((Lisp_Object)); extern void buffer_slot_type_mismatch P_ ((Lisp_Object, int)) NO_RETURN; extern void fix_overlays_before P_ ((struct buffer *, EMACS_INT, EMACS_INT)); extern void mmap_set_vars P_ ((int)); -extern void release_buffer P_ ((struct thread_state *)); /* Get overlays at POSN into array OVERLAYS with NOVERLAYS elements. If NEXTP is non-NULL, return next overlay there. diff --git a/src/thread.c b/src/thread.c index e2e8e6a94e6..92d0c180112 100644 --- a/src/thread.c +++ b/src/thread.c @@ -1,6 +1,7 @@ #include #include "lisp.h" +#include "buffer.h" #include "blockinput.h" #include @@ -11,6 +12,10 @@ void mark_stack P_ ((char *, char *)); void flush_stack_call_func P_ ((void (*) (char *, void *), void *)); +/* condition var .. w/ global lock */ + +static pthread_cond_t buffer_cond; + static struct thread_state primary_thread; static struct thread_state *all_threads = &primary_thread; @@ -97,6 +102,41 @@ unmark_threads (void) unmark_byte_stack (iter->m_byte_stack_list); } +void +thread_acquire_buffer (char *end, void *nb) +{ + struct buffer *new_buffer = nb; + + if (current_buffer) + { + current_buffer->owner = current_buffer->prev_owner; + current_buffer->prev_owner = Qnil; + } + + /* FIXME this check should be in the caller, for better + single-threaded performance. */ + if (other_threads_p () && !thread_inhibit_yield_p ()) + { + /* Let other threads try to acquire a buffer. */ + pthread_cond_broadcast (&buffer_cond); + + /* If our desired buffer is locked, wait for it. */ + while (other_threads_p () + && !current_thread->nolock + && !EQ (new_buffer->owner, Qnil) + /* We set the owner to Qt to mean it is being killed. */ + && !EQ (new_buffer->owner, Qt)) + pthread_cond_wait (&buffer_cond, &global_lock); + } + + /* FIXME: if buffer is killed */ + new_buffer->prev_owner = new_buffer->owner; + if (current_thread->nolock) + new_buffer->owner = Qnil; + else + new_buffer->owner = get_current_thread (); +} + int thread_inhibit_yield_p () { @@ -200,7 +240,12 @@ run_thread (void *state) ; *iter = (*iter)->next_thread; - release_buffer (self); + if (!EQ (self->m_current_buffer->owner, Qt)) + { + self->m_current_buffer->owner = Qnil; + pthread_cond_broadcast (&buffer_cond); + } + xfree (self->m_specpdl); pthread_mutex_unlock (&global_lock); @@ -324,6 +369,8 @@ init_threads (void) pthread_mutex_lock (&global_lock); primary_thread.pthread_id = pthread_self (); primary_thread.nolock = 0; + + pthread_cond_init (&buffer_cond, NULL); } void diff --git a/src/thread.h b/src/thread.h index 982f1b1775a..ac5cb010c57 100644 --- a/src/thread.h +++ b/src/thread.h @@ -97,3 +97,5 @@ extern int user_thread_p P_ ((void)); EXFUN (Finhibit_yield, 1); extern int thread_inhibit_yield_p P_ ((void)); + +extern void thread_acquire_buffer (char *, void *); -- 2.11.4.GIT