aboutsummaryrefslogtreecommitdiffstats
path: root/src/thread.c
diff options
context:
space:
mode:
authorKen Raeburn2015-11-01 01:42:21 -0400
committerKen Raeburn2015-11-01 01:42:21 -0400
commit39372e1a1032521be74575bb06f95a3898fbae30 (patch)
tree754bd242a23d2358ea116126fcb0a629947bd9ec /src/thread.c
parent6a3121904d76e3b2f63007341d48c5c1af55de80 (diff)
parente11aaee266da52937a3a031cb108fe13f68958c3 (diff)
downloademacs-39372e1a1032521be74575bb06f95a3898fbae30.tar.gz
emacs-39372e1a1032521be74575bb06f95a3898fbae30.zip
merge from trunk
Diffstat (limited to 'src/thread.c')
-rw-r--r--src/thread.c80
1 files changed, 41 insertions, 39 deletions
diff --git a/src/thread.c b/src/thread.c
index cd9e916c571..1ff485f0f78 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -33,7 +33,8 @@ static struct thread_state *all_threads = &primary_thread;
33 33
34static sys_mutex_t global_lock; 34static sys_mutex_t global_lock;
35 35
36Lisp_Object Qthreadp, Qmutexp, Qcondition_variable_p; 36extern int poll_suppress_count;
37extern volatile int interrupt_input_blocked;
37 38
38 39
39 40
@@ -265,7 +266,7 @@ mutex_unlock_callback (void *arg)
265 266
266DEFUN ("mutex-unlock", Fmutex_unlock, Smutex_unlock, 1, 1, 0, 267DEFUN ("mutex-unlock", Fmutex_unlock, Smutex_unlock, 1, 1, 0,
267 doc: /* Release the mutex. 268 doc: /* Release the mutex.
268If this thread does not own MUTEX, signal an error. 269If this thread does not own MUTEX, signal an error.
269Otherwise, decrement the mutex's count. If the count is zero, 270Otherwise, decrement the mutex's count. If the count is zero,
270release MUTEX. */) 271release MUTEX. */)
271 (Lisp_Object mutex) 272 (Lisp_Object mutex)
@@ -478,10 +479,10 @@ struct select_args
478{ 479{
479 select_func *func; 480 select_func *func;
480 int max_fds; 481 int max_fds;
481 SELECT_TYPE *rfds; 482 fd_set *rfds;
482 SELECT_TYPE *wfds; 483 fd_set *wfds;
483 SELECT_TYPE *efds; 484 fd_set *efds;
484 EMACS_TIME *timeout; 485 struct timespec *timeout;
485 sigset_t *sigmask; 486 sigset_t *sigmask;
486 int result; 487 int result;
487}; 488};
@@ -499,8 +500,8 @@ really_call_select (void *arg)
499} 500}
500 501
501int 502int
502thread_select (select_func *func, int max_fds, SELECT_TYPE *rfds, 503thread_select (select_func *func, int max_fds, fd_set *rfds,
503 SELECT_TYPE *wfds, SELECT_TYPE *efds, EMACS_TIME *timeout, 504 fd_set *wfds, fd_set *efds, struct timespec *timeout,
504 sigset_t *sigmask) 505 sigset_t *sigmask)
505{ 506{
506 struct select_args sa; 507 struct select_args sa;
@@ -526,30 +527,13 @@ mark_one_thread (struct thread_state *thread)
526 527
527 mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr); 528 mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr);
528 529
529#if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \
530 || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS)
531 mark_stack (thread->m_stack_bottom, thread->stack_top); 530 mark_stack (thread->m_stack_bottom, thread->stack_top);
532#else
533 {
534 struct gcpro *tail;
535 for (tail = thread->m_gcprolist; tail; tail = tail->next)
536 for (i = 0; i < tail->nvars; i++)
537 mark_object (tail->var[i]);
538 }
539
540#if BYTE_MARK_STACK
541 if (thread->m_byte_stack_list)
542 mark_byte_stack (thread->m_byte_stack_list);
543#endif
544
545 mark_catchlist (thread->m_catchlist);
546 531
547 for (handler = thread->m_handlerlist; handler; handler = handler->next) 532 for (handler = thread->m_handlerlist; handler; handler = handler->next)
548 { 533 {
549 mark_object (handler->handler); 534 mark_object (handler->tag_or_ch);
550 mark_object (handler->var); 535 mark_object (handler->val);
551 } 536 }
552#endif
553 537
554 if (thread->m_current_buffer) 538 if (thread->m_current_buffer)
555 { 539 {
@@ -591,7 +575,7 @@ unmark_threads (void)
591 575
592 for (iter = all_threads; iter; iter = iter->next_thread) 576 for (iter = all_threads; iter; iter = iter->next_thread)
593 if (iter->m_byte_stack_list) 577 if (iter->m_byte_stack_list)
594 unmark_byte_stack (iter->m_byte_stack_list); 578 relocate_byte_stack (iter->m_byte_stack_list);
595} 579}
596 580
597 581
@@ -645,6 +629,18 @@ run_thread (void *state)
645 629
646 acquire_global_lock (self); 630 acquire_global_lock (self);
647 631
632 { /* Put a dummy catcher at top-level so that handlerlist is never NULL.
633 This is important since handlerlist->nextfree holds the freelist
634 which would otherwise leak every time we unwind back to top-level. */
635 struct handler *c;
636 handlerlist_sentinel = xzalloc (sizeof (struct handler));
637 handlerlist = handlerlist_sentinel->nextfree = handlerlist_sentinel;
638 PUSH_HANDLER (c, Qunbound, CATCHER);
639 eassert (c == handlerlist_sentinel);
640 handlerlist_sentinel->nextfree = NULL;
641 handlerlist_sentinel->next = NULL;
642 }
643
648 /* It might be nice to do something with errors here. */ 644 /* It might be nice to do something with errors here. */
649 internal_condition_case (invoke_thread_function, Qt, do_nothing); 645 internal_condition_case (invoke_thread_function, Qt, do_nothing);
650 646
@@ -655,6 +651,15 @@ run_thread (void *state)
655 self->m_specpdl_ptr = NULL; 651 self->m_specpdl_ptr = NULL;
656 self->m_specpdl_size = 0; 652 self->m_specpdl_size = 0;
657 653
654 {
655 struct handler *c, *c_next;
656 for (c = handlerlist_sentinel; c; c = c_next)
657 {
658 c_next = c->nextfree;
659 xfree (c);
660 }
661 }
662
658 current_thread = NULL; 663 current_thread = NULL;
659 sys_cond_broadcast (&self->thread_condvar); 664 sys_cond_broadcast (&self->thread_condvar);
660 665
@@ -687,6 +692,7 @@ If NAME is given, it names the new thread. */)
687 struct thread_state *new_thread; 692 struct thread_state *new_thread;
688 Lisp_Object result; 693 Lisp_Object result;
689 const char *c_name = NULL; 694 const char *c_name = NULL;
695 size_t offset = offsetof (struct thread_state, m_byte_stack_list);
690 696
691 /* Can't start a thread in temacs. */ 697 /* Can't start a thread in temacs. */
692 if (!initialized) 698 if (!initialized)
@@ -695,11 +701,10 @@ If NAME is given, it names the new thread. */)
695 if (!NILP (name)) 701 if (!NILP (name))
696 CHECK_STRING (name); 702 CHECK_STRING (name);
697 703
698 new_thread = ALLOCATE_PSEUDOVECTOR (struct thread_state, m_gcprolist, 704 new_thread = ALLOCATE_PSEUDOVECTOR (struct thread_state, m_byte_stack_list,
699 PVEC_THREAD); 705 PVEC_THREAD);
700 memset ((char *) new_thread + offsetof (struct thread_state, m_gcprolist), 706 memset ((char *) new_thread + offset, 0,
701 0, sizeof (struct thread_state) - offsetof (struct thread_state, 707 sizeof (struct thread_state) - offset);
702 m_gcprolist));
703 708
704 new_thread->function = function; 709 new_thread->function = function;
705 new_thread->name = name; 710 new_thread->name = name;
@@ -910,7 +915,7 @@ static void
910init_primary_thread (void) 915init_primary_thread (void)
911{ 916{
912 primary_thread.header.size 917 primary_thread.header.size
913 = PSEUDOVECSIZE (struct thread_state, m_gcprolist); 918 = PSEUDOVECSIZE (struct thread_state, m_byte_stack_list);
914 XSETPVECTYPE (&primary_thread, PVEC_THREAD); 919 XSETPVECTYPE (&primary_thread, PVEC_THREAD);
915 primary_thread.m_last_thing_searched = Qnil; 920 primary_thread.m_last_thing_searched = Qnil;
916 primary_thread.m_saved_last_thing_searched = Qnil; 921 primary_thread.m_saved_last_thing_searched = Qnil;
@@ -965,10 +970,7 @@ syms_of_threads (void)
965 defsubr (&Scondition_name); 970 defsubr (&Scondition_name);
966 } 971 }
967 972
968 Qthreadp = intern_c_string ("threadp"); 973 DEFSYM (Qthreadp, "threadp");
969 staticpro (&Qthreadp); 974 DEFSYM (Qmutexp, "mutexp");
970 Qmutexp = intern_c_string ("mutexp"); 975 DEFSYM (Qcondition_variable_p, "condition-variable-p");
971 staticpro (&Qmutexp);
972 Qcondition_variable_p = intern_c_string ("condition-variable-p");
973 staticpro (&Qcondition_variable_p);
974} 976}