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)
{
#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;
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);
static struct thread_state *all_threads = &primary_thread;
-sys_mutex_t global_lock;
+static sys_mutex_t global_lock;
Lisp_Object Qthreadp, Qmutexp;
\f
+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);
+}
+
+\f
+
+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);
+}
+
+\f
+
DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 1, 0,
doc: /* Create a mutex.
A mutex provides a synchronization point for threads.
\f
-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);
-}
-
-\f
-
struct select_args
{
select_func *func;