From 17dc30054799dab20bdab6da296ad6083cdaecd6 Mon Sep 17 00:00:00 2001 From: Cyrus Harmon Date: Fri, 2 Feb 2007 19:26:23 +0000 Subject: [PATCH] 1.0.2.7: Darwin/MacOS threading improvements * use LOCK_CREATE_THREAD on MacOS/Darwin too * add new mach_exception_lock and grab this lock when handling exceptions * fix signal mask restoring logic (I think...) * restore float state in addition to thread state when done handling an emulated signal --- src/runtime/thread.c | 1 + src/runtime/x86-darwin-os.c | 24 ++++++++++++++++-------- version.lisp-expr | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/runtime/thread.c b/src/runtime/thread.c index 2c3367c..9871f9f 100644 --- a/src/runtime/thread.c +++ b/src/runtime/thread.c @@ -55,6 +55,7 @@ #if defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_SB_THREAD) #define QUEUE_FREEABLE_THREAD_STACKS +#define LOCK_CREATE_THREAD #endif #ifdef LISP_FEATURE_FREEBSD diff --git a/src/runtime/x86-darwin-os.c b/src/runtime/x86-darwin-os.c index feec962..66b49f5 100644 --- a/src/runtime/x86-darwin-os.c +++ b/src/runtime/x86-darwin-os.c @@ -28,6 +28,7 @@ #ifdef LISP_FEATURE_SB_THREAD pthread_mutex_t modify_ldt_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t mach_exception_lock = PTHREAD_MUTEX_INITIALIZER; void set_data_desc_size(data_desc_t* desc, unsigned long size) { @@ -254,7 +255,6 @@ void signal_emulation_wrapper(x86_thread_state32_t *thread_state, struct ucontext *context; struct mcontext *regs; - sigset_t sigmask; context = (struct ucontext*) os_validate(0, sizeof(struct ucontext)); regs = (struct mcontext*) os_validate(0, sizeof(struct mcontext)); @@ -268,22 +268,20 @@ void signal_emulation_wrapper(x86_thread_state32_t *thread_state, 3) call the signal handler 4) restore the sigmask */ - pthread_sigmask(0, NULL, &sigmask); - block_blockable_signals(); - build_fake_signal_context(context, thread_state, float_state); + block_blockable_signals(); + handler(signal, siginfo, context); update_thread_state_from_context(thread_state, float_state, context); - pthread_sigmask(SIG_SETMASK, &sigmask, NULL); - os_invalidate((os_vm_address_t)context, sizeof(struct ucontext)); os_invalidate((os_vm_address_t)regs, sizeof(struct mcontext)); /* Trap to restore the signal context. */ - asm volatile ("movl %0, %%eax; .long 0xffff0b0f": : "r" (thread_state)); + asm volatile ("movl %0, %%eax; movl %1, %%ebx; .long 0xffff0b0f" + : : "r" (thread_state), "r" (float_state)); } #if defined DUMP_CONTEXT @@ -343,6 +341,8 @@ catch_exception_raise(mach_port_t exception_port, int signal; siginfo_t* siginfo; + thread_mutex_lock(&mach_exception_lock); + x86_thread_state32_t thread_state; mach_msg_type_number_t thread_state_count = x86_THREAD_STATE32_COUNT; @@ -429,7 +429,6 @@ catch_exception_raise(mach_port_t exception_port, * exhaustion instead. */ protect_control_stack_guard_page_thread(1, th); protect_control_stack_return_guard_page_thread(0, th); - } else if (addr >= undefined_alien_address && addr < undefined_alien_address + os_vm_page_size) { @@ -499,6 +498,7 @@ catch_exception_raise(mach_port_t exception_port, x86_FLOAT_STATE32, (thread_state_t)&float_state, float_state_count); + thread_mutex_unlock(&mach_exception_lock); return KERN_SUCCESS; case EXC_BAD_INSTRUCTION: @@ -527,6 +527,12 @@ catch_exception_raise(mach_port_t exception_port, (thread_state_t) thread_state.eax, /* &thread_state, */ thread_state_count); + + ret = thread_set_state(thread, + x86_FLOAT_STATE32, + (thread_state_t) thread_state.ebx, + /* &thread_state, */ + float_state_count); } else { backup_thread_state = thread_state; @@ -581,9 +587,11 @@ catch_exception_raise(mach_port_t exception_port, (thread_state_t)&float_state, float_state_count); } + thread_mutex_unlock(&mach_exception_lock); return KERN_SUCCESS; default: + thread_mutex_unlock(&mach_exception_lock); return KERN_INVALID_RIGHT; } } diff --git a/version.lisp-expr b/version.lisp-expr index 0c61444..9f1acac 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.2.6" +"1.0.2.7" -- 1.7.10.4