aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/emacs.c1
-rw-r--r--src/lisp.h8
-rw-r--r--src/search.c6
-rw-r--r--src/thread.c92
-rw-r--r--src/thread.h1
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
1436 if (!initialized) 1436 if (!initialized)
1437 { 1437 {
1438 init_alloc_once (); 1438 init_alloc_once ();
1439 init_threads_once ();
1440 init_obarray_once (); 1439 init_obarray_once ();
1441 init_eval_once (); 1440 init_eval_once ();
1442 init_charset_once (); 1441 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
1279 1279
1280#define XSETPVECTYPE(v, code) \ 1280#define XSETPVECTYPE(v, code) \
1281 ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS)) 1281 ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
1282#define PVECHEADERSIZE(code, lispsize, restsize) \
1283 (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS) \
1284 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) | (lispsize))
1282#define XSETPVECTYPESIZE(v, code, lispsize, restsize) \ 1285#define XSETPVECTYPESIZE(v, code, lispsize, restsize) \
1283 ((v)->header.size = (PSEUDOVECTOR_FLAG \ 1286 ((v)->header.size = PVECHEADERSIZE (code, lispsize, restsize))
1284 | ((code) << PSEUDOVECTOR_AREA_BITS) \
1285 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \
1286 | (lispsize)))
1287 1287
1288/* The cast to union vectorlike_header * avoids aliasing issues. */ 1288/* The cast to union vectorlike_header * avoids aliasing issues. */
1289#define XSETPSEUDOVECTOR(a, b, code) \ 1289#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)
3387 Fput (Qinvalid_regexp, Qerror_message, 3387 Fput (Qinvalid_regexp, Qerror_message,
3388 build_pure_c_string ("Invalid regexp")); 3388 build_pure_c_string ("Invalid regexp"));
3389 3389
3390 last_thing_searched = Qnil;
3391 staticpro (&last_thing_searched);
3392
3393 saved_last_thing_searched = Qnil;
3394 staticpro (&saved_last_thing_searched);
3395
3396 re_match_object = Qnil; 3390 re_match_object = Qnil;
3397 staticpro (&re_match_object); 3391 staticpro (&re_match_object);
3398 3392
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);
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 *);
287extern void finalize_one_condvar (struct Lisp_CondVar *); 287extern void finalize_one_condvar (struct Lisp_CondVar *);
288extern void maybe_reacquire_global_lock (void); 288extern void maybe_reacquire_global_lock (void);
289 289
290extern void init_threads_once (void);
291extern void init_threads (void); 290extern void init_threads (void);
292extern void syms_of_threads (void); 291extern void syms_of_threads (void);
293extern bool main_thread_p (const void *); 292extern bool main_thread_p (const void *);