From 4c90369d77d3db1cbd37df7857e4706176fd7ba2 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 24 Apr 2019 13:35:14 -0700 Subject: [PATCH] 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. --- src/emacs.c | 1 - src/lisp.h | 8 ++--- src/search.c | 6 ---- src/thread.c | 92 +++++++++++++++++----------------------------------- src/thread.h | 1 - 5 files changed, 34 insertions(+), 74 deletions(-) diff --git a/src/emacs.c b/src/emacs.c index 8655f715e47..86d2bc65ac7 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1436,7 +1436,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem if (!initialized) { init_alloc_once (); - init_threads_once (); init_obarray_once (); init_eval_once (); init_charset_once (); diff --git a/src/lisp.h b/src/lisp.h index 703fe76d64e..70b2aa270e0 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1279,11 +1279,11 @@ INLINE bool #define XSETPVECTYPE(v, code) \ ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS)) +#define PVECHEADERSIZE(code, lispsize, restsize) \ + (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \ + | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize)) #define XSETPVECTYPESIZE(v, code, lispsize, restsize) \ - ((v)->header.size = (PSEUDOVECTOR_FLAG \ - | ((code) << PSEUDOVECTOR_AREA_BITS) \ - | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \ - | (lispsize))) + ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize)) /* The cast to union vectorlike_header * avoids aliasing issues. */ #define XSETPSEUDOVECTOR(a, b, code) \ diff --git a/src/search.c b/src/search.c index 7a6e680685a..dfbae5c9628 100644 --- a/src/search.c +++ b/src/search.c @@ -3387,12 +3387,6 @@ syms_of_search (void) Fput (Qinvalid_regexp, Qerror_message, build_pure_c_string ("Invalid regexp")); - last_thing_searched = Qnil; - staticpro (&last_thing_searched); - - saved_last_thing_searched = Qnil; - staticpro (&saved_last_thing_searched); - re_match_object = Qnil; staticpro (&re_match_object); 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 }; verify (GCALIGNED (union aligned_thread_state)); -static union aligned_thread_state main_thread; +static union aligned_thread_state main_thread + = {{ + .header.size = PVECHEADERSIZE (PVEC_THREAD, + PSEUDOVECSIZE (struct thread_state, + event_object), + VECSIZE (struct thread_state)), + .m_last_thing_searched = LISPSYM_INITIALLY (Qnil), + .m_saved_last_thing_searched = LISPSYM_INITIALLY (Qnil), + .name = LISPSYM_INITIALLY (Qnil), + .function = LISPSYM_INITIALLY (Qnil), + .result = LISPSYM_INITIALLY (Qnil), + .error_symbol = LISPSYM_INITIALLY (Qnil), + .error_data = LISPSYM_INITIALLY (Qnil), + .event_object = LISPSYM_INITIALLY (Qnil), + }}; struct thread_state *current_thread = &main_thread.s; @@ -261,19 +275,15 @@ NAME, if given, is used as the name of the mutex. The name is informational only. */) (Lisp_Object name) { - struct Lisp_Mutex *mutex; - Lisp_Object result; - if (!NILP (name)) CHECK_STRING (name); - mutex = ALLOCATE_PSEUDOVECTOR (struct Lisp_Mutex, name, PVEC_MUTEX); - memset ((char *) mutex + offsetof (struct Lisp_Mutex, mutex), - 0, sizeof (struct Lisp_Mutex) - offsetof (struct Lisp_Mutex, - mutex)); + struct Lisp_Mutex *mutex + = ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_Mutex, name, PVEC_MUTEX); mutex->name = name; lisp_mutex_init (&mutex->mutex); + Lisp_Object result; XSETMUTEX (result, mutex); return result; } @@ -379,21 +389,17 @@ NAME, if given, is the name of this condition variable. The name is informational only. */) (Lisp_Object mutex, Lisp_Object name) { - struct Lisp_CondVar *condvar; - Lisp_Object result; - CHECK_MUTEX (mutex); if (!NILP (name)) CHECK_STRING (name); - condvar = ALLOCATE_PSEUDOVECTOR (struct Lisp_CondVar, name, PVEC_CONDVAR); - memset ((char *) condvar + offsetof (struct Lisp_CondVar, cond), - 0, sizeof (struct Lisp_CondVar) - offsetof (struct Lisp_CondVar, - cond)); + struct Lisp_CondVar *condvar + = ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_CondVar, name, PVEC_CONDVAR); condvar->mutex = mutex; condvar->name = name; sys_cond_init (&condvar->cond); + Lisp_Object result; XSETCONDVAR (result, condvar); return result; } @@ -637,10 +643,8 @@ mark_one_thread (struct thread_state *thread) mark_object (tem); } - mark_object (thread->m_last_thing_searched); - - if (!NILP (thread->m_saved_last_thing_searched)) - mark_object (thread->m_saved_last_thing_searched); + /* No need to mark Lisp_Object members like m_last_thing_searched, + as mark_threads_callback does that by calling mark_object. */ } static void @@ -792,12 +796,6 @@ When the function exits, the thread dies. If NAME is given, it must be a string; it names the new thread. */) (Lisp_Object function, Lisp_Object name) { - sys_thread_t thr; - struct thread_state *new_thread; - Lisp_Object result; - const char *c_name = NULL; - size_t offset = offsetof (struct thread_state, m_stack_bottom); - /* Can't start a thread in temacs. */ if (!initialized) emacs_abort (); @@ -805,20 +803,13 @@ If NAME is given, it must be a string; it names the new thread. */) if (!NILP (name)) CHECK_STRING (name); - new_thread = ALLOCATE_PSEUDOVECTOR (struct thread_state, event_object, - PVEC_THREAD); - memset ((char *) new_thread + offset, 0, - sizeof (struct thread_state) - offset); - + struct thread_state *new_thread + = ALLOCATE_ZEROED_PSEUDOVECTOR (struct thread_state, event_object, + PVEC_THREAD); new_thread->function = function; new_thread->name = name; - new_thread->m_last_thing_searched = Qnil; /* copy from parent? */ - new_thread->m_saved_last_thing_searched = Qnil; + /* Perhaps copy m_last_thing_searched from parent? */ new_thread->m_current_buffer = current_thread->m_current_buffer; - new_thread->result = Qnil; - new_thread->error_symbol = Qnil; - new_thread->error_data = Qnil; - new_thread->event_object = Qnil; new_thread->m_specpdl_size = 50; 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. */) new_thread->next_thread = all_threads; all_threads = new_thread; - if (!NILP (name)) - c_name = SSDATA (ENCODE_UTF_8 (name)); - + char const *c_name = !NILP (name) ? SSDATA (ENCODE_UTF_8 (name)) : NULL; + sys_thread_t thr; if (! sys_thread_create (&thr, c_name, run_thread, new_thread)) { /* Restore the previous situation. */ @@ -848,6 +838,7 @@ If NAME is given, it must be a string; it names the new thread. */) } /* FIXME: race here where new thread might not be filled in? */ + Lisp_Object result; XSETTHREAD (result, new_thread); return result; } @@ -1060,22 +1051,6 @@ thread_check_current_buffer (struct buffer *buffer) -static void -init_main_thread (void) -{ - main_thread.s.header.size - = PSEUDOVECSIZE (struct thread_state, event_object); - XSETPVECTYPE (&main_thread.s, PVEC_THREAD); - main_thread.s.m_last_thing_searched = Qnil; - main_thread.s.m_saved_last_thing_searched = Qnil; - main_thread.s.name = Qnil; - main_thread.s.function = Qnil; - main_thread.s.result = Qnil; - main_thread.s.error_symbol = Qnil; - main_thread.s.error_data = Qnil; - main_thread.s.event_object = Qnil; -} - bool main_thread_p (const void *ptr) { @@ -1090,16 +1065,9 @@ in_current_thread (void) return sys_thread_equal (sys_thread_self (), current_thread->thread_id); } -void -init_threads_once (void) -{ - init_main_thread (); -} - void init_threads (void) { - init_main_thread (); sys_cond_init (&main_thread.s.thread_condvar); sys_mutex_init (&global_lock); sys_mutex_lock (&global_lock); diff --git a/src/thread.h b/src/thread.h index 0514669a87d..498b9909c9f 100644 --- a/src/thread.h +++ b/src/thread.h @@ -287,7 +287,6 @@ extern void finalize_one_mutex (struct Lisp_Mutex *); extern void finalize_one_condvar (struct Lisp_CondVar *); extern void maybe_reacquire_global_lock (void); -extern void init_threads_once (void); extern void init_threads (void); extern void syms_of_threads (void); extern bool main_thread_p (const void *); -- 2.39.2