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:
parent
f52cfea0dc
commit
b3c78ffa31
4 changed files with 121 additions and 128 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
154
src/thread.c
154
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;
|
||||
|
|
|
|||
16
src/thread.h
16
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 *);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue