aboutsummaryrefslogtreecommitdiffstats
path: root/src/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/thread.c')
-rw-r--r--src/thread.c111
1 files changed, 46 insertions, 65 deletions
diff --git a/src/thread.c b/src/thread.c
index 6612697b95e..e2deadd7a83 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -1,5 +1,5 @@
1/* Threading code. 1/* Threading code.
2Copyright (C) 2012-2018 Free Software Foundation, Inc. 2Copyright (C) 2012-2019 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
25#include "process.h" 25#include "process.h"
26#include "coding.h" 26#include "coding.h"
27#include "syssignal.h" 27#include "syssignal.h"
28#include "pdumper.h"
28#include "keyboard.h" 29#include "keyboard.h"
29 30
30union aligned_thread_state 31union aligned_thread_state
@@ -34,7 +35,21 @@ union aligned_thread_state
34}; 35};
35verify (GCALIGNED (union aligned_thread_state)); 36verify (GCALIGNED (union aligned_thread_state));
36 37
37static union aligned_thread_state main_thread; 38static union aligned_thread_state main_thread
39 = {{
40 .header.size = PVECHEADERSIZE (PVEC_THREAD,
41 PSEUDOVECSIZE (struct thread_state,
42 event_object),
43 VECSIZE (struct thread_state)),
44 .m_last_thing_searched = LISPSYM_INITIALLY (Qnil),
45 .m_saved_last_thing_searched = LISPSYM_INITIALLY (Qnil),
46 .name = LISPSYM_INITIALLY (Qnil),
47 .function = LISPSYM_INITIALLY (Qnil),
48 .result = LISPSYM_INITIALLY (Qnil),
49 .error_symbol = LISPSYM_INITIALLY (Qnil),
50 .error_data = LISPSYM_INITIALLY (Qnil),
51 .event_object = LISPSYM_INITIALLY (Qnil),
52 }};
38 53
39struct thread_state *current_thread = &main_thread.s; 54struct thread_state *current_thread = &main_thread.s;
40 55
@@ -260,19 +275,15 @@ NAME, if given, is used as the name of the mutex. The name is
260informational only. */) 275informational only. */)
261 (Lisp_Object name) 276 (Lisp_Object name)
262{ 277{
263 struct Lisp_Mutex *mutex;
264 Lisp_Object result;
265
266 if (!NILP (name)) 278 if (!NILP (name))
267 CHECK_STRING (name); 279 CHECK_STRING (name);
268 280
269 mutex = ALLOCATE_PSEUDOVECTOR (struct Lisp_Mutex, mutex, PVEC_MUTEX); 281 struct Lisp_Mutex *mutex
270 memset ((char *) mutex + offsetof (struct Lisp_Mutex, mutex), 282 = ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_Mutex, name, PVEC_MUTEX);
271 0, sizeof (struct Lisp_Mutex) - offsetof (struct Lisp_Mutex,
272 mutex));
273 mutex->name = name; 283 mutex->name = name;
274 lisp_mutex_init (&mutex->mutex); 284 lisp_mutex_init (&mutex->mutex);
275 285
286 Lisp_Object result;
276 XSETMUTEX (result, mutex); 287 XSETMUTEX (result, mutex);
277 return result; 288 return result;
278} 289}
@@ -378,21 +389,17 @@ NAME, if given, is the name of this condition variable. The name is
378informational only. */) 389informational only. */)
379 (Lisp_Object mutex, Lisp_Object name) 390 (Lisp_Object mutex, Lisp_Object name)
380{ 391{
381 struct Lisp_CondVar *condvar;
382 Lisp_Object result;
383
384 CHECK_MUTEX (mutex); 392 CHECK_MUTEX (mutex);
385 if (!NILP (name)) 393 if (!NILP (name))
386 CHECK_STRING (name); 394 CHECK_STRING (name);
387 395
388 condvar = ALLOCATE_PSEUDOVECTOR (struct Lisp_CondVar, cond, PVEC_CONDVAR); 396 struct Lisp_CondVar *condvar
389 memset ((char *) condvar + offsetof (struct Lisp_CondVar, cond), 397 = ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_CondVar, name, PVEC_CONDVAR);
390 0, sizeof (struct Lisp_CondVar) - offsetof (struct Lisp_CondVar,
391 cond));
392 condvar->mutex = mutex; 398 condvar->mutex = mutex;
393 condvar->name = name; 399 condvar->name = name;
394 sys_cond_init (&condvar->cond); 400 sys_cond_init (&condvar->cond);
395 401
402 Lisp_Object result;
396 XSETCONDVAR (result, condvar); 403 XSETCONDVAR (result, condvar);
397 return result; 404 return result;
398} 405}
@@ -616,7 +623,7 @@ static void
616mark_one_thread (struct thread_state *thread) 623mark_one_thread (struct thread_state *thread)
617{ 624{
618 /* Get the stack top now, in case mark_specpdl changes it. */ 625 /* Get the stack top now, in case mark_specpdl changes it. */
619 void *stack_top = thread->stack_top; 626 void const *stack_top = thread->stack_top;
620 627
621 mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr); 628 mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr);
622 629
@@ -636,10 +643,8 @@ mark_one_thread (struct thread_state *thread)
636 mark_object (tem); 643 mark_object (tem);
637 } 644 }
638 645
639 mark_object (thread->m_last_thing_searched); 646 /* No need to mark Lisp_Object members like m_last_thing_searched,
640 647 as mark_threads_callback does that by calling mark_object. */
641 if (!NILP (thread->m_saved_last_thing_searched))
642 mark_object (thread->m_saved_last_thing_searched);
643} 648}
644 649
645static void 650static void
@@ -767,9 +772,21 @@ run_thread (void *state)
767 return NULL; 772 return NULL;
768} 773}
769 774
775static void
776free_search_regs (struct re_registers *regs)
777{
778 if (regs->num_regs != 0)
779 {
780 xfree (regs->start);
781 xfree (regs->end);
782 }
783}
784
770void 785void
771finalize_one_thread (struct thread_state *state) 786finalize_one_thread (struct thread_state *state)
772{ 787{
788 free_search_regs (&state->m_search_regs);
789 free_search_regs (&state->m_saved_search_regs);
773 sys_cond_destroy (&state->thread_condvar); 790 sys_cond_destroy (&state->thread_condvar);
774} 791}
775 792
@@ -779,12 +796,6 @@ When the function exits, the thread dies.
779If NAME is given, it must be a string; it names the new thread. */) 796If NAME is given, it must be a string; it names the new thread. */)
780 (Lisp_Object function, Lisp_Object name) 797 (Lisp_Object function, Lisp_Object name)
781{ 798{
782 sys_thread_t thr;
783 struct thread_state *new_thread;
784 Lisp_Object result;
785 const char *c_name = NULL;
786 size_t offset = offsetof (struct thread_state, m_stack_bottom);
787
788 /* Can't start a thread in temacs. */ 799 /* Can't start a thread in temacs. */
789 if (!initialized) 800 if (!initialized)
790 emacs_abort (); 801 emacs_abort ();
@@ -792,20 +803,13 @@ If NAME is given, it must be a string; it names the new thread. */)
792 if (!NILP (name)) 803 if (!NILP (name))
793 CHECK_STRING (name); 804 CHECK_STRING (name);
794 805
795 new_thread = ALLOCATE_PSEUDOVECTOR (struct thread_state, m_stack_bottom, 806 struct thread_state *new_thread
796 PVEC_THREAD); 807 = ALLOCATE_ZEROED_PSEUDOVECTOR (struct thread_state, event_object,
797 memset ((char *) new_thread + offset, 0, 808 PVEC_THREAD);
798 sizeof (struct thread_state) - offset);
799
800 new_thread->function = function; 809 new_thread->function = function;
801 new_thread->name = name; 810 new_thread->name = name;
802 new_thread->m_last_thing_searched = Qnil; /* copy from parent? */ 811 /* Perhaps copy m_last_thing_searched from parent? */
803 new_thread->m_saved_last_thing_searched = Qnil;
804 new_thread->m_current_buffer = current_thread->m_current_buffer; 812 new_thread->m_current_buffer = current_thread->m_current_buffer;
805 new_thread->result = Qnil;
806 new_thread->error_symbol = Qnil;
807 new_thread->error_data = Qnil;
808 new_thread->event_object = Qnil;
809 813
810 new_thread->m_specpdl_size = 50; 814 new_thread->m_specpdl_size = 50;
811 new_thread->m_specpdl = xmalloc ((1 + new_thread->m_specpdl_size) 815 new_thread->m_specpdl = xmalloc ((1 + new_thread->m_specpdl_size)
@@ -820,9 +824,8 @@ If NAME is given, it must be a string; it names the new thread. */)
820 new_thread->next_thread = all_threads; 824 new_thread->next_thread = all_threads;
821 all_threads = new_thread; 825 all_threads = new_thread;
822 826
823 if (!NILP (name)) 827 char const *c_name = !NILP (name) ? SSDATA (ENCODE_UTF_8 (name)) : NULL;
824 c_name = SSDATA (ENCODE_UTF_8 (name)); 828 sys_thread_t thr;
825
826 if (! sys_thread_create (&thr, c_name, run_thread, new_thread)) 829 if (! sys_thread_create (&thr, c_name, run_thread, new_thread))
827 { 830 {
828 /* Restore the previous situation. */ 831 /* Restore the previous situation. */
@@ -835,6 +838,7 @@ If NAME is given, it must be a string; it names the new thread. */)
835 } 838 }
836 839
837 /* FIXME: race here where new thread might not be filled in? */ 840 /* FIXME: race here where new thread might not be filled in? */
841 Lisp_Object result;
838 XSETTHREAD (result, new_thread); 842 XSETTHREAD (result, new_thread);
839 return result; 843 return result;
840} 844}
@@ -1047,24 +1051,8 @@ thread_check_current_buffer (struct buffer *buffer)
1047 1051
1048 1052
1049 1053
1050static void
1051init_main_thread (void)
1052{
1053 main_thread.s.header.size
1054 = PSEUDOVECSIZE (struct thread_state, m_stack_bottom);
1055 XSETPVECTYPE (&main_thread.s, PVEC_THREAD);
1056 main_thread.s.m_last_thing_searched = Qnil;
1057 main_thread.s.m_saved_last_thing_searched = Qnil;
1058 main_thread.s.name = Qnil;
1059 main_thread.s.function = Qnil;
1060 main_thread.s.result = Qnil;
1061 main_thread.s.error_symbol = Qnil;
1062 main_thread.s.error_data = Qnil;
1063 main_thread.s.event_object = Qnil;
1064}
1065
1066bool 1054bool
1067main_thread_p (void *ptr) 1055main_thread_p (const void *ptr)
1068{ 1056{
1069 return ptr == &main_thread.s; 1057 return ptr == &main_thread.s;
1070} 1058}
@@ -1078,15 +1066,8 @@ in_current_thread (void)
1078} 1066}
1079 1067
1080void 1068void
1081init_threads_once (void)
1082{
1083 init_main_thread ();
1084}
1085
1086void
1087init_threads (void) 1069init_threads (void)
1088{ 1070{
1089 init_main_thread ();
1090 sys_cond_init (&main_thread.s.thread_condvar); 1071 sys_cond_init (&main_thread.s.thread_condvar);
1091 sys_mutex_init (&global_lock); 1072 sys_mutex_init (&global_lock);
1092 sys_mutex_lock (&global_lock); 1073 sys_mutex_lock (&global_lock);