aboutsummaryrefslogtreecommitdiffstats
path: root/src/thread.c
diff options
context:
space:
mode:
authorPaul Eggert2019-04-24 13:35:14 -0700
committerPaul Eggert2019-04-24 13:37:15 -0700
commit4c90369d77d3db1cbd37df7857e4706176fd7ba2 (patch)
tree424f9c8b819feef66314316974290bd7f1edc8fd /src/thread.c
parentc5358e831f05cdd110f12a4260e6fb607c66c0b4 (diff)
downloademacs-4c90369d77d3db1cbd37df7857e4706176fd7ba2.tar.gz
emacs-4c90369d77d3db1cbd37df7857e4706176fd7ba2.zip
Simplify thread initialization and GC
* src/lisp.h (PVECHEADERSIZE): New macro. (XSETPVECTYPESIZE): Use it. * src/search.c (syms_of_search): No need to initialize or staticpro last_thing_searched or saved_last_thing_searched, as the thread code arranges for initialization and GC. * src/thread.c (main_thread): Initialize statically. (Fmake_mutex, Fmake_condition_variable, Fmake_thread): Use ALLOCATE_ZEROED_PSEUDOVECTOR rather than zeroing by hand. (mark_one_thread): No need to mark Lisp_Object members. (init_main_thread, init_threads_once): Remove. All uses removed.
Diffstat (limited to 'src/thread.c')
-rw-r--r--src/thread.c92
1 files changed, 30 insertions, 62 deletions
diff --git a/src/thread.c b/src/thread.c
index 670680f2b0d..e2deadd7a83 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -35,7 +35,21 @@ union aligned_thread_state
35}; 35};
36verify (GCALIGNED (union aligned_thread_state)); 36verify (GCALIGNED (union aligned_thread_state));
37 37
38static 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 }};
39 53
40struct thread_state *current_thread = &main_thread.s; 54struct thread_state *current_thread = &main_thread.s;
41 55
@@ -261,19 +275,15 @@ NAME, if given, is used as the name of the mutex. The name is
261informational only. */) 275informational only. */)
262 (Lisp_Object name) 276 (Lisp_Object name)
263{ 277{
264 struct Lisp_Mutex *mutex;
265 Lisp_Object result;
266
267 if (!NILP (name)) 278 if (!NILP (name))
268 CHECK_STRING (name); 279 CHECK_STRING (name);
269 280
270 mutex = ALLOCATE_PSEUDOVECTOR (struct Lisp_Mutex, name, PVEC_MUTEX); 281 struct Lisp_Mutex *mutex
271 memset ((char *) mutex + offsetof (struct Lisp_Mutex, mutex), 282 = ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_Mutex, name, PVEC_MUTEX);
272 0, sizeof (struct Lisp_Mutex) - offsetof (struct Lisp_Mutex,
273 mutex));
274 mutex->name = name; 283 mutex->name = name;
275 lisp_mutex_init (&mutex->mutex); 284 lisp_mutex_init (&mutex->mutex);
276 285
286 Lisp_Object result;
277 XSETMUTEX (result, mutex); 287 XSETMUTEX (result, mutex);
278 return result; 288 return result;
279} 289}
@@ -379,21 +389,17 @@ NAME, if given, is the name of this condition variable. The name is
379informational only. */) 389informational only. */)
380 (Lisp_Object mutex, Lisp_Object name) 390 (Lisp_Object mutex, Lisp_Object name)
381{ 391{
382 struct Lisp_CondVar *condvar;
383 Lisp_Object result;
384
385 CHECK_MUTEX (mutex); 392 CHECK_MUTEX (mutex);
386 if (!NILP (name)) 393 if (!NILP (name))
387 CHECK_STRING (name); 394 CHECK_STRING (name);
388 395
389 condvar = ALLOCATE_PSEUDOVECTOR (struct Lisp_CondVar, name, PVEC_CONDVAR); 396 struct Lisp_CondVar *condvar
390 memset ((char *) condvar + offsetof (struct Lisp_CondVar, cond), 397 = ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_CondVar, name, PVEC_CONDVAR);
391 0, sizeof (struct Lisp_CondVar) - offsetof (struct Lisp_CondVar,
392 cond));
393 condvar->mutex = mutex; 398 condvar->mutex = mutex;
394 condvar->name = name; 399 condvar->name = name;
395 sys_cond_init (&condvar->cond); 400 sys_cond_init (&condvar->cond);
396 401
402 Lisp_Object result;
397 XSETCONDVAR (result, condvar); 403 XSETCONDVAR (result, condvar);
398 return result; 404 return result;
399} 405}
@@ -637,10 +643,8 @@ mark_one_thread (struct thread_state *thread)
637 mark_object (tem); 643 mark_object (tem);
638 } 644 }
639 645
640 mark_object (thread->m_last_thing_searched); 646 /* No need to mark Lisp_Object members like m_last_thing_searched,
641 647 as mark_threads_callback does that by calling mark_object. */
642 if (!NILP (thread->m_saved_last_thing_searched))
643 mark_object (thread->m_saved_last_thing_searched);
644} 648}
645 649
646static void 650static void
@@ -792,12 +796,6 @@ When the function exits, the thread dies.
792If 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. */)
793 (Lisp_Object function, Lisp_Object name) 797 (Lisp_Object function, Lisp_Object name)
794{ 798{
795 sys_thread_t thr;
796 struct thread_state *new_thread;
797 Lisp_Object result;
798 const char *c_name = NULL;
799 size_t offset = offsetof (struct thread_state, m_stack_bottom);
800
801 /* Can't start a thread in temacs. */ 799 /* Can't start a thread in temacs. */
802 if (!initialized) 800 if (!initialized)
803 emacs_abort (); 801 emacs_abort ();
@@ -805,20 +803,13 @@ If NAME is given, it must be a string; it names the new thread. */)
805 if (!NILP (name)) 803 if (!NILP (name))
806 CHECK_STRING (name); 804 CHECK_STRING (name);
807 805
808 new_thread = ALLOCATE_PSEUDOVECTOR (struct thread_state, event_object, 806 struct thread_state *new_thread
809 PVEC_THREAD); 807 = ALLOCATE_ZEROED_PSEUDOVECTOR (struct thread_state, event_object,
810 memset ((char *) new_thread + offset, 0, 808 PVEC_THREAD);
811 sizeof (struct thread_state) - offset);
812
813 new_thread->function = function; 809 new_thread->function = function;
814 new_thread->name = name; 810 new_thread->name = name;
815 new_thread->m_last_thing_searched = Qnil; /* copy from parent? */ 811 /* Perhaps copy m_last_thing_searched from parent? */
816 new_thread->m_saved_last_thing_searched = Qnil;
817 new_thread->m_current_buffer = current_thread->m_current_buffer; 812 new_thread->m_current_buffer = current_thread->m_current_buffer;
818 new_thread->result = Qnil;
819 new_thread->error_symbol = Qnil;
820 new_thread->error_data = Qnil;
821 new_thread->event_object = Qnil;
822 813
823 new_thread->m_specpdl_size = 50; 814 new_thread->m_specpdl_size = 50;
824 new_thread->m_specpdl = xmalloc ((1 + new_thread->m_specpdl_size) 815 new_thread->m_specpdl = xmalloc ((1 + new_thread->m_specpdl_size)
@@ -833,9 +824,8 @@ If NAME is given, it must be a string; it names the new thread. */)
833 new_thread->next_thread = all_threads; 824 new_thread->next_thread = all_threads;
834 all_threads = new_thread; 825 all_threads = new_thread;
835 826
836 if (!NILP (name)) 827 char const *c_name = !NILP (name) ? SSDATA (ENCODE_UTF_8 (name)) : NULL;
837 c_name = SSDATA (ENCODE_UTF_8 (name)); 828 sys_thread_t thr;
838
839 if (! sys_thread_create (&thr, c_name, run_thread, new_thread)) 829 if (! sys_thread_create (&thr, c_name, run_thread, new_thread))
840 { 830 {
841 /* Restore the previous situation. */ 831 /* Restore the previous situation. */
@@ -848,6 +838,7 @@ If NAME is given, it must be a string; it names the new thread. */)
848 } 838 }
849 839
850 /* 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;
851 XSETTHREAD (result, new_thread); 842 XSETTHREAD (result, new_thread);
852 return result; 843 return result;
853} 844}
@@ -1060,22 +1051,6 @@ thread_check_current_buffer (struct buffer *buffer)
1060 1051
1061 1052
1062 1053
1063static void
1064init_main_thread (void)
1065{
1066 main_thread.s.header.size
1067 = PSEUDOVECSIZE (struct thread_state, event_object);
1068 XSETPVECTYPE (&main_thread.s, PVEC_THREAD);
1069 main_thread.s.m_last_thing_searched = Qnil;
1070 main_thread.s.m_saved_last_thing_searched = Qnil;
1071 main_thread.s.name = Qnil;
1072 main_thread.s.function = Qnil;
1073 main_thread.s.result = Qnil;
1074 main_thread.s.error_symbol = Qnil;
1075 main_thread.s.error_data = Qnil;
1076 main_thread.s.event_object = Qnil;
1077}
1078
1079bool 1054bool
1080main_thread_p (const void *ptr) 1055main_thread_p (const void *ptr)
1081{ 1056{
@@ -1091,15 +1066,8 @@ in_current_thread (void)
1091} 1066}
1092 1067
1093void 1068void
1094init_threads_once (void)
1095{
1096 init_main_thread ();
1097}
1098
1099void
1100init_threads (void) 1069init_threads (void)
1101{ 1070{
1102 init_main_thread ();
1103 sys_cond_init (&main_thread.s.thread_condvar); 1071 sys_cond_init (&main_thread.s.thread_condvar);
1104 sys_mutex_init (&global_lock); 1072 sys_mutex_init (&global_lock);
1105 sys_mutex_lock (&global_lock); 1073 sys_mutex_lock (&global_lock);