1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-08 12:40:49 -08:00

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.
This commit is contained in:
Tom Tromey 2012-08-18 19:59:47 -06:00
parent f52cfea0dc
commit b3c78ffa31
4 changed files with 121 additions and 128 deletions

View file

@ -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)
{

View file

@ -23,19 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <pthread.h>
/* 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);

View file

@ -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;

View file

@ -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 *);