2 Copyright (C) 2012-2016 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23 #include "character.h"
27 #include "syssignal.h"
29 static struct thread_state primary_thread
;
31 struct thread_state
*current_thread
= &primary_thread
;
33 static struct thread_state
*all_threads
= &primary_thread
;
35 static sys_mutex_t global_lock
;
37 extern int poll_suppress_count
;
38 extern volatile int interrupt_input_blocked
;
42 /* m_specpdl is set when the thread is created and cleared when the
44 #define thread_alive_p(STATE) ((STATE)->m_specpdl != NULL)
49 release_global_lock (void)
51 sys_mutex_unlock (&global_lock
);
54 /* You must call this after acquiring the global lock.
55 acquire_global_lock does it for you. */
57 post_acquire_global_lock (struct thread_state
*self
)
59 struct thread_state
*prev_thread
= current_thread
;
61 /* Do this early on, so that code below could signal errors (e.g.,
62 unbind_for_thread_switch might) correctly, because we are already
63 running in the context of the thread pointed by SELF. */
64 current_thread
= self
;
66 if (prev_thread
!= current_thread
)
68 /* PREV_THREAD is NULL if the previously current thread
69 exited. In this case, there is no reason to unbind, and
71 if (prev_thread
!= NULL
)
72 unbind_for_thread_switch (prev_thread
);
73 rebind_for_thread_switch ();
75 /* Set the new thread's current buffer. This needs to be done
76 even if it is the same buffer as that of the previous thread,
77 because of thread-local bindings. */
78 set_buffer_internal_2 (current_buffer
);
81 /* We could have been signaled while waiting to grab the global lock
82 for the first time since this thread was created, in which case
83 we didn't yet have the opportunity to set up the handlers. Delay
84 raising the signal in that case (it will be actually raised when
85 the thread comes here after acquiring the lock the next time). */
86 if (!NILP (current_thread
->error_symbol
) && handlerlist
)
88 Lisp_Object sym
= current_thread
->error_symbol
;
89 Lisp_Object data
= current_thread
->error_data
;
91 current_thread
->error_symbol
= Qnil
;
92 current_thread
->error_data
= Qnil
;
98 acquire_global_lock (struct thread_state
*self
)
100 sys_mutex_lock (&global_lock
);
101 post_acquire_global_lock (self
);
104 /* This is called from keyboard.c when it detects that SIGINT
105 interrupted thread_select before the current thread could acquire
106 the lock. We must acquire the lock to prevent a thread from
107 running without holding the global lock, and to avoid repeated
108 calls to sys_mutex_unlock, which invokes undefined behavior. */
110 maybe_reacquire_global_lock (void)
112 if (current_thread
->not_holding_lock
)
114 struct thread_state
*self
= current_thread
;
116 acquire_global_lock (self
);
117 current_thread
->not_holding_lock
= 0;
124 lisp_mutex_init (lisp_mutex_t
*mutex
)
128 sys_cond_init (&mutex
->condition
);
132 lisp_mutex_lock (lisp_mutex_t
*mutex
, int new_count
)
134 struct thread_state
*self
;
136 if (mutex
->owner
== NULL
)
138 mutex
->owner
= current_thread
;
139 mutex
->count
= new_count
== 0 ? 1 : new_count
;
142 if (mutex
->owner
== current_thread
)
144 eassert (new_count
== 0);
149 self
= current_thread
;
150 self
->wait_condvar
= &mutex
->condition
;
151 while (mutex
->owner
!= NULL
&& (new_count
!= 0
152 || NILP (self
->error_symbol
)))
153 sys_cond_wait (&mutex
->condition
, &global_lock
);
154 self
->wait_condvar
= NULL
;
156 if (new_count
== 0 && !NILP (self
->error_symbol
))
160 mutex
->count
= new_count
== 0 ? 1 : new_count
;
166 lisp_mutex_unlock (lisp_mutex_t
*mutex
)
168 if (mutex
->owner
!= current_thread
)
169 error ("Cannot unlock mutex owned by another thread");
171 if (--mutex
->count
> 0)
175 sys_cond_broadcast (&mutex
->condition
);
181 lisp_mutex_unlock_for_wait (lisp_mutex_t
*mutex
)
183 unsigned int result
= mutex
->count
;
185 /* Ensured by condvar code. */
186 eassert (mutex
->owner
== current_thread
);
190 sys_cond_broadcast (&mutex
->condition
);
196 lisp_mutex_destroy (lisp_mutex_t
*mutex
)
198 sys_cond_destroy (&mutex
->condition
);
202 lisp_mutex_owned_p (lisp_mutex_t
*mutex
)
204 return mutex
->owner
== current_thread
;
209 DEFUN ("make-mutex", Fmake_mutex
, Smake_mutex
, 0, 1, 0,
210 doc
: /* Create a mutex.
211 A mutex provides a synchronization point for threads.
212 Only one thread at a time can hold a mutex. Other threads attempting
213 to acquire it will block until the mutex is available.
215 A thread can acquire a mutex any number of times.
217 NAME, if given, is used as the name of the mutex. The name is
218 informational only. */)
221 struct Lisp_Mutex
*mutex
;
227 mutex
= ALLOCATE_PSEUDOVECTOR (struct Lisp_Mutex
, mutex
, PVEC_MUTEX
);
228 memset ((char *) mutex
+ offsetof (struct Lisp_Mutex
, mutex
),
229 0, sizeof (struct Lisp_Mutex
) - offsetof (struct Lisp_Mutex
,
232 lisp_mutex_init (&mutex
->mutex
);
234 XSETMUTEX (result
, mutex
);
239 mutex_lock_callback (void *arg
)
241 struct Lisp_Mutex
*mutex
= arg
;
242 struct thread_state
*self
= current_thread
;
244 if (lisp_mutex_lock (&mutex
->mutex
, 0))
245 post_acquire_global_lock (self
);
249 do_unwind_mutex_lock (void)
251 current_thread
->event_object
= Qnil
;
254 DEFUN ("mutex-lock", Fmutex_lock
, Smutex_lock
, 1, 1, 0,
255 doc
: /* Acquire a mutex.
256 If the current thread already owns MUTEX, increment the count and
258 Otherwise, if no thread owns MUTEX, make the current thread own it.
259 Otherwise, block until MUTEX is available, or until the current thread
260 is signaled using `thread-signal'.
261 Note that calls to `mutex-lock' and `mutex-unlock' must be paired. */)
264 struct Lisp_Mutex
*lmutex
;
265 ptrdiff_t count
= SPECPDL_INDEX ();
268 lmutex
= XMUTEX (mutex
);
270 current_thread
->event_object
= mutex
;
271 record_unwind_protect_void (do_unwind_mutex_lock
);
272 flush_stack_call_func (mutex_lock_callback
, lmutex
);
273 return unbind_to (count
, Qnil
);
277 mutex_unlock_callback (void *arg
)
279 struct Lisp_Mutex
*mutex
= arg
;
280 struct thread_state
*self
= current_thread
;
282 if (lisp_mutex_unlock (&mutex
->mutex
))
283 post_acquire_global_lock (self
);
286 DEFUN ("mutex-unlock", Fmutex_unlock
, Smutex_unlock
, 1, 1, 0,
287 doc
: /* Release the mutex.
288 If this thread does not own MUTEX, signal an error.
289 Otherwise, decrement the mutex's count. If the count is zero,
293 struct Lisp_Mutex
*lmutex
;
296 lmutex
= XMUTEX (mutex
);
298 flush_stack_call_func (mutex_unlock_callback
, lmutex
);
302 DEFUN ("mutex-name", Fmutex_name
, Smutex_name
, 1, 1, 0,
303 doc
: /* Return the name of MUTEX.
304 If no name was given when MUTEX was created, return nil. */)
307 struct Lisp_Mutex
*lmutex
;
310 lmutex
= XMUTEX (mutex
);
316 finalize_one_mutex (struct Lisp_Mutex
*mutex
)
318 lisp_mutex_destroy (&mutex
->mutex
);
323 DEFUN ("make-condition-variable",
324 Fmake_condition_variable
, Smake_condition_variable
,
326 doc
: /* Make a condition variable associated with MUTEX.
327 A condition variable provides a way for a thread to sleep while
328 waiting for a state change.
330 MUTEX is the mutex associated with this condition variable.
331 NAME, if given, is the name of this condition variable. The name is
332 informational only. */)
333 (Lisp_Object mutex
, Lisp_Object name
)
335 struct Lisp_CondVar
*condvar
;
342 condvar
= ALLOCATE_PSEUDOVECTOR (struct Lisp_CondVar
, cond
, PVEC_CONDVAR
);
343 memset ((char *) condvar
+ offsetof (struct Lisp_CondVar
, cond
),
344 0, sizeof (struct Lisp_CondVar
) - offsetof (struct Lisp_CondVar
,
346 condvar
->mutex
= mutex
;
347 condvar
->name
= name
;
348 sys_cond_init (&condvar
->cond
);
350 XSETCONDVAR (result
, condvar
);
355 condition_wait_callback (void *arg
)
357 struct Lisp_CondVar
*cvar
= arg
;
358 struct Lisp_Mutex
*mutex
= XMUTEX (cvar
->mutex
);
359 struct thread_state
*self
= current_thread
;
360 unsigned int saved_count
;
363 XSETCONDVAR (cond
, cvar
);
364 self
->event_object
= cond
;
365 saved_count
= lisp_mutex_unlock_for_wait (&mutex
->mutex
);
366 /* If signaled while unlocking, skip the wait but reacquire the lock. */
367 if (NILP (self
->error_symbol
))
369 self
->wait_condvar
= &cvar
->cond
;
370 sys_cond_wait (&cvar
->cond
, &global_lock
);
371 self
->wait_condvar
= NULL
;
373 lisp_mutex_lock (&mutex
->mutex
, saved_count
);
374 self
->event_object
= Qnil
;
375 post_acquire_global_lock (self
);
378 DEFUN ("condition-wait", Fcondition_wait
, Scondition_wait
, 1, 1, 0,
379 doc
: /* Wait for the condition variable COND to be notified.
380 COND is the condition variable to wait on.
382 The mutex associated with COND must be held when this is called.
383 It is an error if it is not held.
385 This releases the mutex and waits for COND to be notified or for
386 this thread to be signaled with `thread-signal'. When
387 `condition-wait' returns, COND's mutex will again be locked by
391 struct Lisp_CondVar
*cvar
;
392 struct Lisp_Mutex
*mutex
;
394 CHECK_CONDVAR (cond
);
395 cvar
= XCONDVAR (cond
);
397 mutex
= XMUTEX (cvar
->mutex
);
398 if (!lisp_mutex_owned_p (&mutex
->mutex
))
399 error ("Condition variable's mutex is not held by current thread");
401 flush_stack_call_func (condition_wait_callback
, cvar
);
406 /* Used to communicate arguments to condition_notify_callback. */
409 struct Lisp_CondVar
*cvar
;
414 condition_notify_callback (void *arg
)
416 struct notify_args
*na
= arg
;
417 struct Lisp_Mutex
*mutex
= XMUTEX (na
->cvar
->mutex
);
418 struct thread_state
*self
= current_thread
;
419 unsigned int saved_count
;
422 XSETCONDVAR (cond
, na
->cvar
);
423 saved_count
= lisp_mutex_unlock_for_wait (&mutex
->mutex
);
425 sys_cond_broadcast (&na
->cvar
->cond
);
427 sys_cond_signal (&na
->cvar
->cond
);
428 lisp_mutex_lock (&mutex
->mutex
, saved_count
);
429 post_acquire_global_lock (self
);
432 DEFUN ("condition-notify", Fcondition_notify
, Scondition_notify
, 1, 2, 0,
433 doc
: /* Notify COND, a condition variable.
434 This wakes a thread waiting on COND.
435 If ALL is non-nil, all waiting threads are awoken.
437 The mutex associated with COND must be held when this is called.
438 It is an error if it is not held.
440 This releases COND's mutex when notifying COND. When
441 `condition-notify' returns, the mutex will again be locked by this
443 (Lisp_Object cond
, Lisp_Object all
)
445 struct Lisp_CondVar
*cvar
;
446 struct Lisp_Mutex
*mutex
;
447 struct notify_args args
;
449 CHECK_CONDVAR (cond
);
450 cvar
= XCONDVAR (cond
);
452 mutex
= XMUTEX (cvar
->mutex
);
453 if (!lisp_mutex_owned_p (&mutex
->mutex
))
454 error ("Condition variable's mutex is not held by current thread");
457 args
.all
= !NILP (all
);
458 flush_stack_call_func (condition_notify_callback
, &args
);
463 DEFUN ("condition-mutex", Fcondition_mutex
, Scondition_mutex
, 1, 1, 0,
464 doc
: /* Return the mutex associated with condition variable COND. */)
467 struct Lisp_CondVar
*cvar
;
469 CHECK_CONDVAR (cond
);
470 cvar
= XCONDVAR (cond
);
475 DEFUN ("condition-name", Fcondition_name
, Scondition_name
, 1, 1, 0,
476 doc
: /* Return the name of condition variable COND.
477 If no name was given when COND was created, return nil. */)
480 struct Lisp_CondVar
*cvar
;
482 CHECK_CONDVAR (cond
);
483 cvar
= XCONDVAR (cond
);
489 finalize_one_condvar (struct Lisp_CondVar
*condvar
)
491 sys_cond_destroy (&condvar
->cond
);
503 struct timespec
*timeout
;
509 really_call_select (void *arg
)
511 struct select_args
*sa
= arg
;
512 struct thread_state
*self
= current_thread
;
515 block_interrupt_signal (&oldset
);
516 self
->not_holding_lock
= 1;
517 release_global_lock ();
518 restore_signal_mask (&oldset
);
520 sa
->result
= (sa
->func
) (sa
->max_fds
, sa
->rfds
, sa
->wfds
, sa
->efds
,
521 sa
->timeout
, sa
->sigmask
);
523 block_interrupt_signal (&oldset
);
524 acquire_global_lock (self
);
525 self
->not_holding_lock
= 0;
526 restore_signal_mask (&oldset
);
530 thread_select (select_func
*func
, int max_fds
, fd_set
*rfds
,
531 fd_set
*wfds
, fd_set
*efds
, struct timespec
*timeout
,
534 struct select_args sa
;
537 sa
.max_fds
= max_fds
;
541 sa
.timeout
= timeout
;
542 sa
.sigmask
= sigmask
;
543 flush_stack_call_func (really_call_select
, &sa
);
550 mark_one_thread (struct thread_state
*thread
)
552 struct handler
*handler
;
555 mark_specpdl (thread
->m_specpdl
, thread
->m_specpdl_ptr
);
557 mark_stack (thread
->m_stack_bottom
, thread
->stack_top
);
559 for (handler
= thread
->m_handlerlist
; handler
; handler
= handler
->next
)
561 mark_object (handler
->tag_or_ch
);
562 mark_object (handler
->val
);
565 if (thread
->m_current_buffer
)
567 XSETBUFFER (tem
, thread
->m_current_buffer
);
571 mark_object (thread
->m_last_thing_searched
);
573 if (!NILP (thread
->m_saved_last_thing_searched
))
574 mark_object (thread
->m_saved_last_thing_searched
);
578 mark_threads_callback (void *ignore
)
580 struct thread_state
*iter
;
582 for (iter
= all_threads
; iter
; iter
= iter
->next_thread
)
584 Lisp_Object thread_obj
;
586 XSETTHREAD (thread_obj
, iter
);
587 mark_object (thread_obj
);
588 mark_one_thread (iter
);
595 flush_stack_call_func (mark_threads_callback
, NULL
);
599 unmark_threads (void)
601 struct thread_state
*iter
;
603 for (iter
= all_threads
; iter
; iter
= iter
->next_thread
)
604 if (iter
->m_byte_stack_list
)
605 relocate_byte_stack (iter
->m_byte_stack_list
);
611 yield_callback (void *ignore
)
613 struct thread_state
*self
= current_thread
;
615 release_global_lock ();
617 acquire_global_lock (self
);
620 DEFUN ("thread-yield", Fthread_yield
, Sthread_yield
, 0, 0, 0,
621 doc
: /* Yield the CPU to another thread. */)
624 flush_stack_call_func (yield_callback
, NULL
);
629 invoke_thread_function (void)
631 int count
= SPECPDL_INDEX ();
633 Ffuncall (1, ¤t_thread
->function
);
634 return unbind_to (count
, Qnil
);
638 do_nothing (Lisp_Object whatever
)
644 run_thread (void *state
)
646 /* Make sure stack_top and m_stack_bottom are properly aligned as GC
654 struct thread_state
*self
= state
;
655 struct thread_state
**iter
;
657 self
->m_stack_bottom
= &stack_pos
.c
;
658 self
->stack_top
= &stack_pos
.c
;
659 self
->thread_id
= sys_thread_self ();
661 acquire_global_lock (self
);
663 /* Put a dummy catcher at top-level so that handlerlist is never NULL.
664 This is important since handlerlist->nextfree holds the freelist
665 which would otherwise leak every time we unwind back to top-level. */
666 handlerlist_sentinel
= xzalloc (sizeof (struct handler
));
667 handlerlist
= handlerlist_sentinel
->nextfree
= handlerlist_sentinel
;
668 struct handler
*c
= push_handler (Qunbound
, CATCHER
);
669 eassert (c
== handlerlist_sentinel
);
670 handlerlist_sentinel
->nextfree
= NULL
;
671 handlerlist_sentinel
->next
= NULL
;
673 /* It might be nice to do something with errors here. */
674 internal_condition_case (invoke_thread_function
, Qt
, do_nothing
);
676 update_processes_for_thread_death (Fcurrent_thread ());
678 xfree (self
->m_specpdl
- 1);
679 self
->m_specpdl
= NULL
;
680 self
->m_specpdl_ptr
= NULL
;
681 self
->m_specpdl_size
= 0;
684 struct handler
*c
, *c_next
;
685 for (c
= handlerlist_sentinel
; c
; c
= c_next
)
687 c_next
= c
->nextfree
;
692 current_thread
= NULL
;
693 sys_cond_broadcast (&self
->thread_condvar
);
695 /* Unlink this thread from the list of all threads. Note that we
696 have to do this very late, after broadcasting our death.
697 Otherwise the GC may decide to reap the thread_state object,
698 leading to crashes. */
699 for (iter
= &all_threads
; *iter
!= self
; iter
= &(*iter
)->next_thread
)
701 *iter
= (*iter
)->next_thread
;
703 release_global_lock ();
709 finalize_one_thread (struct thread_state
*state
)
711 sys_cond_destroy (&state
->thread_condvar
);
714 DEFUN ("make-thread", Fmake_thread
, Smake_thread
, 1, 2, 0,
715 doc
: /* Start a new thread and run FUNCTION in it.
716 When the function exits, the thread dies.
717 If NAME is given, it must be a string; it names the new thread. */)
718 (Lisp_Object function
, Lisp_Object name
)
721 struct thread_state
*new_thread
;
723 const char *c_name
= NULL
;
724 size_t offset
= offsetof (struct thread_state
, m_byte_stack_list
);
726 /* Can't start a thread in temacs. */
733 new_thread
= ALLOCATE_PSEUDOVECTOR (struct thread_state
, m_byte_stack_list
,
735 memset ((char *) new_thread
+ offset
, 0,
736 sizeof (struct thread_state
) - offset
);
738 new_thread
->function
= function
;
739 new_thread
->name
= name
;
740 new_thread
->m_last_thing_searched
= Qnil
; /* copy from parent? */
741 new_thread
->m_saved_last_thing_searched
= Qnil
;
742 new_thread
->m_current_buffer
= current_thread
->m_current_buffer
;
743 new_thread
->error_symbol
= Qnil
;
744 new_thread
->error_data
= Qnil
;
745 new_thread
->event_object
= Qnil
;
747 new_thread
->m_specpdl_size
= 50;
748 new_thread
->m_specpdl
= xmalloc ((1 + new_thread
->m_specpdl_size
)
749 * sizeof (union specbinding
));
750 /* Skip the dummy entry. */
751 ++new_thread
->m_specpdl
;
752 new_thread
->m_specpdl_ptr
= new_thread
->m_specpdl
;
754 sys_cond_init (&new_thread
->thread_condvar
);
756 /* We'll need locking here eventually. */
757 new_thread
->next_thread
= all_threads
;
758 all_threads
= new_thread
;
761 c_name
= SSDATA (ENCODE_UTF_8 (name
));
763 if (! sys_thread_create (&thr
, c_name
, run_thread
, new_thread
))
765 /* Restore the previous situation. */
766 all_threads
= all_threads
->next_thread
;
767 error ("Could not start a new thread");
770 /* FIXME: race here where new thread might not be filled in? */
771 XSETTHREAD (result
, new_thread
);
775 DEFUN ("current-thread", Fcurrent_thread
, Scurrent_thread
, 0, 0, 0,
776 doc
: /* Return the current thread. */)
780 XSETTHREAD (result
, current_thread
);
784 DEFUN ("thread-name", Fthread_name
, Sthread_name
, 1, 1, 0,
785 doc
: /* Return the name of the THREAD.
786 The name is the same object that was passed to `make-thread'. */)
789 struct thread_state
*tstate
;
791 CHECK_THREAD (thread
);
792 tstate
= XTHREAD (thread
);
798 thread_signal_callback (void *arg
)
800 struct thread_state
*tstate
= arg
;
801 struct thread_state
*self
= current_thread
;
803 sys_cond_broadcast (tstate
->wait_condvar
);
804 post_acquire_global_lock (self
);
807 DEFUN ("thread-signal", Fthread_signal
, Sthread_signal
, 3, 3, 0,
808 doc
: /* Signal an error in a thread.
809 This acts like `signal', but arranges for the signal to be raised
810 in THREAD. If THREAD is the current thread, acts just like `signal'.
811 This will interrupt a blocked call to `mutex-lock', `condition-wait',
812 or `thread-join' in the target thread. */)
813 (Lisp_Object thread
, Lisp_Object error_symbol
, Lisp_Object data
)
815 struct thread_state
*tstate
;
817 CHECK_THREAD (thread
);
818 tstate
= XTHREAD (thread
);
820 if (tstate
== current_thread
)
821 Fsignal (error_symbol
, data
);
823 /* What to do if thread is already signaled? */
824 /* What if error_symbol is Qnil? */
825 tstate
->error_symbol
= error_symbol
;
826 tstate
->error_data
= data
;
828 if (tstate
->wait_condvar
)
829 flush_stack_call_func (thread_signal_callback
, tstate
);
834 DEFUN ("thread-alive-p", Fthread_alive_p
, Sthread_alive_p
, 1, 1, 0,
835 doc
: /* Return t if THREAD is alive, or nil if it has exited. */)
838 struct thread_state
*tstate
;
840 CHECK_THREAD (thread
);
841 tstate
= XTHREAD (thread
);
843 return thread_alive_p (tstate
) ? Qt
: Qnil
;
846 DEFUN ("thread--blocker", Fthread_blocker
, Sthread_blocker
, 1, 1, 0,
847 doc
: /* Return the object that THREAD is blocking on.
848 If THREAD is blocked in `thread-join' on a second thread, return that
850 If THREAD is blocked in `mutex-lock', return the mutex.
851 If THREAD is blocked in `condition-wait', return the condition variable.
852 Otherwise, if THREAD is not blocked, return nil. */)
855 struct thread_state
*tstate
;
857 CHECK_THREAD (thread
);
858 tstate
= XTHREAD (thread
);
860 return tstate
->event_object
;
864 thread_join_callback (void *arg
)
866 struct thread_state
*tstate
= arg
;
867 struct thread_state
*self
= current_thread
;
870 XSETTHREAD (thread
, tstate
);
871 self
->event_object
= thread
;
872 self
->wait_condvar
= &tstate
->thread_condvar
;
873 while (thread_alive_p (tstate
) && NILP (self
->error_symbol
))
874 sys_cond_wait (self
->wait_condvar
, &global_lock
);
876 self
->wait_condvar
= NULL
;
877 self
->event_object
= Qnil
;
878 post_acquire_global_lock (self
);
881 DEFUN ("thread-join", Fthread_join
, Sthread_join
, 1, 1, 0,
882 doc
: /* Wait for THREAD to exit.
883 This blocks the current thread until THREAD exits or until
884 the current thread is signaled.
885 It is an error for a thread to try to join itself. */)
888 struct thread_state
*tstate
;
890 CHECK_THREAD (thread
);
891 tstate
= XTHREAD (thread
);
893 if (tstate
== current_thread
)
894 error ("Cannot join current thread");
896 if (thread_alive_p (tstate
))
897 flush_stack_call_func (thread_join_callback
, tstate
);
902 DEFUN ("all-threads", Fall_threads
, Sall_threads
, 0, 0, 0,
903 doc
: /* Return a list of all the live threads. */)
906 Lisp_Object result
= Qnil
;
907 struct thread_state
*iter
;
909 for (iter
= all_threads
; iter
; iter
= iter
->next_thread
)
911 if (thread_alive_p (iter
))
915 XSETTHREAD (thread
, iter
);
916 result
= Fcons (thread
, result
);
926 thread_check_current_buffer (struct buffer
*buffer
)
928 struct thread_state
*iter
;
930 for (iter
= all_threads
; iter
; iter
= iter
->next_thread
)
932 if (iter
== current_thread
)
935 if (iter
->m_current_buffer
== buffer
)
945 init_primary_thread (void)
947 primary_thread
.header
.size
948 = PSEUDOVECSIZE (struct thread_state
, m_byte_stack_list
);
949 XSETPVECTYPE (&primary_thread
, PVEC_THREAD
);
950 primary_thread
.m_last_thing_searched
= Qnil
;
951 primary_thread
.m_saved_last_thing_searched
= Qnil
;
952 primary_thread
.name
= Qnil
;
953 primary_thread
.function
= Qnil
;
954 primary_thread
.error_symbol
= Qnil
;
955 primary_thread
.error_data
= Qnil
;
956 primary_thread
.event_object
= Qnil
;
960 primary_thread_p (void *ptr
)
962 return (ptr
== &primary_thread
) ? true : false;
966 init_threads_once (void)
968 init_primary_thread ();
974 init_primary_thread ();
975 sys_cond_init (&primary_thread
.thread_condvar
);
976 sys_mutex_init (&global_lock
);
977 sys_mutex_lock (&global_lock
);
978 current_thread
= &primary_thread
;
979 primary_thread
.thread_id
= sys_thread_self ();
983 syms_of_threads (void)
985 #ifndef THREADS_ENABLED
989 defsubr (&Sthread_yield
);
990 defsubr (&Smake_thread
);
991 defsubr (&Scurrent_thread
);
992 defsubr (&Sthread_name
);
993 defsubr (&Sthread_signal
);
994 defsubr (&Sthread_alive_p
);
995 defsubr (&Sthread_join
);
996 defsubr (&Sthread_blocker
);
997 defsubr (&Sall_threads
);
998 defsubr (&Smake_mutex
);
999 defsubr (&Smutex_lock
);
1000 defsubr (&Smutex_unlock
);
1001 defsubr (&Smutex_name
);
1002 defsubr (&Smake_condition_variable
);
1003 defsubr (&Scondition_wait
);
1004 defsubr (&Scondition_notify
);
1005 defsubr (&Scondition_mutex
);
1006 defsubr (&Scondition_name
);
1009 DEFSYM (Qthreadp
, "threadp");
1010 DEFSYM (Qmutexp
, "mutexp");
1011 DEFSYM (Qcondition_variable_p
, "condition-variable-p");