diff options
| author | YAMAMOTO Mitsuharu | 2019-04-27 18:33:39 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2019-04-27 18:33:39 +0900 |
| commit | 886bedb36c7b959b7e6fc8ce8e0c04e144b0ae28 (patch) | |
| tree | b5770d9fc10a704ad8aeb3474c6940121252c770 /src/thread.c | |
| parent | 015a6e1df2772bd43680df5cbeaffccf98a881da (diff) | |
| parent | 8dc00b2f1e6523c634df3e24379afbe712a32b27 (diff) | |
| download | emacs-886bedb36c7b959b7e6fc8ce8e0c04e144b0ae28.tar.gz emacs-886bedb36c7b959b7e6fc8ce8e0c04e144b0ae28.zip | |
Merge branch 'master' into harfbuzz
Diffstat (limited to 'src/thread.c')
| -rw-r--r-- | src/thread.c | 111 |
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. |
| 2 | Copyright (C) 2012-2018 Free Software Foundation, Inc. | 2 | Copyright (C) 2012-2019 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This 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 | ||
| 30 | union aligned_thread_state | 31 | union aligned_thread_state |
| @@ -34,7 +35,21 @@ union aligned_thread_state | |||
| 34 | }; | 35 | }; |
| 35 | verify (GCALIGNED (union aligned_thread_state)); | 36 | verify (GCALIGNED (union aligned_thread_state)); |
| 36 | 37 | ||
| 37 | static union aligned_thread_state main_thread; | 38 | static 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 | ||
| 39 | struct thread_state *current_thread = &main_thread.s; | 54 | struct 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 | |||
| 260 | informational only. */) | 275 | informational 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 | |||
| 378 | informational only. */) | 389 | informational 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 | |||
| 616 | mark_one_thread (struct thread_state *thread) | 623 | mark_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 | ||
| 645 | static void | 650 | static void |
| @@ -767,9 +772,21 @@ run_thread (void *state) | |||
| 767 | return NULL; | 772 | return NULL; |
| 768 | } | 773 | } |
| 769 | 774 | ||
| 775 | static void | ||
| 776 | free_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 | |||
| 770 | void | 785 | void |
| 771 | finalize_one_thread (struct thread_state *state) | 786 | finalize_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. | |||
| 779 | If NAME is given, it must be a string; it names the new thread. */) | 796 | If 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 | ||
| 1050 | static void | ||
| 1051 | init_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 | |||
| 1066 | bool | 1054 | bool |
| 1067 | main_thread_p (void *ptr) | 1055 | main_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 | ||
| 1080 | void | 1068 | void |
| 1081 | init_threads_once (void) | ||
| 1082 | { | ||
| 1083 | init_main_thread (); | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | void | ||
| 1087 | init_threads (void) | 1069 | init_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); |