Commit 4c90369d authored by Paul Eggert's avatar Paul Eggert

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.
parent c5358e83
Pipeline #1444 passed with stage
in 54 minutes and 13 seconds
......@@ -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 ();
......
......@@ -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) \
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment