diff options
| author | Ken Raeburn | 2015-11-01 01:42:21 -0400 |
|---|---|---|
| committer | Ken Raeburn | 2015-11-01 01:42:21 -0400 |
| commit | 39372e1a1032521be74575bb06f95a3898fbae30 (patch) | |
| tree | 754bd242a23d2358ea116126fcb0a629947bd9ec /src/thread.c | |
| parent | 6a3121904d76e3b2f63007341d48c5c1af55de80 (diff) | |
| parent | e11aaee266da52937a3a031cb108fe13f68958c3 (diff) | |
| download | emacs-39372e1a1032521be74575bb06f95a3898fbae30.tar.gz emacs-39372e1a1032521be74575bb06f95a3898fbae30.zip | |
merge from trunk
Diffstat (limited to 'src/thread.c')
| -rw-r--r-- | src/thread.c | 80 |
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 | ||
| 34 | static sys_mutex_t global_lock; | 34 | static sys_mutex_t global_lock; |
| 35 | 35 | ||
| 36 | Lisp_Object Qthreadp, Qmutexp, Qcondition_variable_p; | 36 | extern int poll_suppress_count; |
| 37 | extern volatile int interrupt_input_blocked; | ||
| 37 | 38 | ||
| 38 | 39 | ||
| 39 | 40 | ||
| @@ -265,7 +266,7 @@ mutex_unlock_callback (void *arg) | |||
| 265 | 266 | ||
| 266 | DEFUN ("mutex-unlock", Fmutex_unlock, Smutex_unlock, 1, 1, 0, | 267 | DEFUN ("mutex-unlock", Fmutex_unlock, Smutex_unlock, 1, 1, 0, |
| 267 | doc: /* Release the mutex. | 268 | doc: /* Release the mutex. |
| 268 | If this thread does not own MUTEX, signal an error. | 269 | If this thread does not own MUTEX, signal an error. |
| 269 | Otherwise, decrement the mutex's count. If the count is zero, | 270 | Otherwise, decrement the mutex's count. If the count is zero, |
| 270 | release MUTEX. */) | 271 | release 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 | ||
| 501 | int | 502 | int |
| 502 | thread_select (select_func *func, int max_fds, SELECT_TYPE *rfds, | 503 | thread_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 | |||
| 910 | init_primary_thread (void) | 915 | init_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 | } |