From b3c78ffa31af4fb96cc18da887e2f2a1e68f5e09 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 18 Aug 2012 19:59:47 -0600 Subject: [PATCH] refactor systhread.h This refactors systhread.h to move the notion of a "lisp mutex" into thread.c. This lets us make make the global lock and post_acquire_global_lock static. --- src/systhread.c | 61 ------------------- src/systhread.h | 18 ------ src/thread.c | 154 +++++++++++++++++++++++++++++++++--------------- src/thread.h | 16 ++++- 4 files changed, 121 insertions(+), 128 deletions(-) diff --git a/src/systhread.c b/src/systhread.c index 968620bcd1c..666641c24da 100644 --- a/src/systhread.c +++ b/src/systhread.c @@ -78,67 +78,6 @@ sys_cond_destroy (sys_cond_t *cond) pthread_cond_destroy (cond); } -void -lisp_mutex_init (lisp_mutex_t *mutex) -{ - mutex->owner = NULL; - mutex->count = 0; - /* A lisp "mutex" is really a condition variable. */ - pthread_cond_init (&mutex->condition, NULL); -} - -void -lisp_mutex_lock (lisp_mutex_t *mutex) -{ - struct thread_state *self; - - if (mutex->owner == NULL) - { - mutex->owner = current_thread; - mutex->count = 1; - return; - } - if (mutex->owner == current_thread) - { - ++mutex->count; - return; - } - - self = current_thread; - self->wait_condvar = &mutex->condition; - while (mutex->owner != NULL && EQ (self->error_symbol, Qnil)) - pthread_cond_wait (&mutex->condition, &global_lock); - self->wait_condvar = NULL; - - post_acquire_global_lock (self); - - mutex->owner = self; - mutex->count = 1; -} - -void -lisp_mutex_unlock (lisp_mutex_t *mutex) -{ - struct thread_state *self = current_thread; - - if (mutex->owner != current_thread) - error ("blah"); - - if (--mutex->count > 0) - return; - - mutex->owner = NULL; - pthread_cond_broadcast (&mutex->condition); - - post_acquire_global_lock (self); -} - -void -lisp_mutex_destroy (lisp_mutex_t *mutex) -{ - sys_cond_destroy (&mutex->condition); -} - sys_thread_t sys_thread_self (void) { diff --git a/src/systhread.h b/src/systhread.h index bf9358c21c6..790b385b7ff 100644 --- a/src/systhread.h +++ b/src/systhread.h @@ -23,19 +23,6 @@ along with GNU Emacs. If not, see . */ #include -/* A mutex in lisp is represented by a pthread condition variable. - The pthread mutex associated with this condition variable is the - global lock. - - Using a condition variable lets us implement interruptibility for - lisp mutexes. */ -typedef struct -{ - struct thread_state *owner; - unsigned int count; - pthread_cond_t condition; -} lisp_mutex_t; - /* A system mutex is just a pthread mutex. This is only used for the GIL. */ typedef pthread_mutex_t sys_mutex_t; @@ -64,11 +51,6 @@ extern void sys_cond_signal (sys_cond_t *); extern void sys_cond_broadcast (sys_cond_t *); extern void sys_cond_destroy (sys_cond_t *); -extern void lisp_mutex_init (lisp_mutex_t *); -extern void lisp_mutex_lock (lisp_mutex_t *); -extern void lisp_mutex_unlock (lisp_mutex_t *); -extern void lisp_mutex_destroy (lisp_mutex_t *); - extern sys_thread_t sys_thread_self (void); extern int sys_thread_equal (sys_thread_t, sys_thread_t); diff --git a/src/thread.c b/src/thread.c index e8e43c5e402..9c39b84eb50 100644 --- a/src/thread.c +++ b/src/thread.c @@ -30,12 +30,119 @@ struct thread_state *current_thread = &primary_thread; static struct thread_state *all_threads = &primary_thread; -sys_mutex_t global_lock; +static sys_mutex_t global_lock; Lisp_Object Qthreadp, Qmutexp; +static void +release_global_lock (void) +{ + sys_mutex_unlock (&global_lock); +} + +/* You must call this after acquiring the global lock. + acquire_global_lock does it for you. */ +static void +post_acquire_global_lock (struct thread_state *self) +{ + Lisp_Object buffer; + + if (self != current_thread) + { + unbind_for_thread_switch (); + current_thread = self; + rebind_for_thread_switch (); + } + + /* We need special handling to re-set the buffer. */ + XSETBUFFER (buffer, self->m_current_buffer); + self->m_current_buffer = 0; + set_buffer_internal (XBUFFER (buffer)); + + if (!EQ (current_thread->error_symbol, Qnil)) + { + Lisp_Object sym = current_thread->error_symbol; + Lisp_Object data = current_thread->error_data; + + current_thread->error_symbol = Qnil; + current_thread->error_data = Qnil; + Fsignal (sym, data); + } +} + +static void +acquire_global_lock (struct thread_state *self) +{ + sys_mutex_lock (&global_lock); + post_acquire_global_lock (self); +} + + + +static void +lisp_mutex_init (lisp_mutex_t *mutex) +{ + mutex->owner = NULL; + mutex->count = 0; + sys_cond_init (&mutex->condition); +} + +static void +lisp_mutex_lock (lisp_mutex_t *mutex) +{ + struct thread_state *self; + + if (mutex->owner == NULL) + { + mutex->owner = current_thread; + mutex->count = 1; + return; + } + if (mutex->owner == current_thread) + { + ++mutex->count; + return; + } + + self = current_thread; + self->wait_condvar = &mutex->condition; + while (mutex->owner != NULL && EQ (self->error_symbol, Qnil)) + sys_cond_wait (&mutex->condition, &global_lock); + self->wait_condvar = NULL; + + post_acquire_global_lock (self); + + mutex->owner = self; + mutex->count = 1; +} + +static void +lisp_mutex_unlock (lisp_mutex_t *mutex) +{ + struct thread_state *self = current_thread; + + if (mutex->owner != current_thread) + error ("blah"); + + if (--mutex->count > 0) + return; + + mutex->owner = NULL; + sys_cond_broadcast (&mutex->condition); + + post_acquire_global_lock (self); +} + +static void +lisp_mutex_destroy (lisp_mutex_t *mutex) +{ + sys_cond_destroy (&mutex->condition); +} + + + DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 1, 0, doc: /* Create a mutex. A mutex provides a synchronization point for threads. @@ -146,51 +253,6 @@ finalize_one_mutex (struct Lisp_Mutex *mutex) -static void -release_global_lock (void) -{ - sys_mutex_unlock (&global_lock); -} - -/* You must call this after acquiring the global lock. - acquire_global_lock does it for you. */ -void -post_acquire_global_lock (struct thread_state *self) -{ - Lisp_Object buffer; - - if (self != current_thread) - { - unbind_for_thread_switch (); - current_thread = self; - rebind_for_thread_switch (); - } - - /* We need special handling to re-set the buffer. */ - XSETBUFFER (buffer, self->m_current_buffer); - self->m_current_buffer = 0; - set_buffer_internal (XBUFFER (buffer)); - - if (!EQ (current_thread->error_symbol, Qnil)) - { - Lisp_Object sym = current_thread->error_symbol; - Lisp_Object data = current_thread->error_data; - - current_thread->error_symbol = Qnil; - current_thread->error_data = Qnil; - Fsignal (sym, data); - } -} - -static void -acquire_global_lock (struct thread_state *self) -{ - sys_mutex_lock (&global_lock); - post_acquire_global_lock (self); -} - - - struct select_args { select_func *func; diff --git a/src/thread.h b/src/thread.h index 9db3c795653..32ef48f63ff 100644 --- a/src/thread.h +++ b/src/thread.h @@ -187,6 +187,19 @@ struct thread_state struct thread_state *next_thread; }; +/* A mutex in lisp is represented by a pthread condition variable. + The system mutex associated with this condition variable is the + global lock. + + Using a condition variable lets us implement interruptibility for + lisp mutexes. */ +typedef struct +{ + struct thread_state *owner; + unsigned int count; + sys_cond_t condition; +} lisp_mutex_t; + struct Lisp_Mutex { struct vectorlike_header header; @@ -198,9 +211,6 @@ struct Lisp_Mutex extern struct thread_state *current_thread; -extern sys_mutex_t global_lock; -extern void post_acquire_global_lock (struct thread_state *); - extern void unmark_threads (void); extern void finalize_one_thread (struct thread_state *state); extern void finalize_one_mutex (struct Lisp_Mutex *); -- 2.39.5