diff --git a/src/mzscheme/gc2/sighand.c b/src/mzscheme/gc2/sighand.c index eea8aeef28..6512d3b61e 100644 --- a/src/mzscheme/gc2/sighand.c +++ b/src/mzscheme/gc2/sighand.c @@ -1,6 +1,6 @@ /* Provides: - initialize_signal_handler(); + initialize_signal_handler(GCTYPE *gc) remove_signal_handler(); Requires: generations_available - mutable int, Windows only @@ -147,7 +147,11 @@ void fault_handler(int sn, siginfo_t *si, void *ctx) static void initialize_signal_handler(GCTYPE *gc) { # ifdef NEED_OSX_MACH_HANDLER - macosx_init_exception_handler(); +# if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) + macosx_init_exception_handler(MASTERGC == 0); +# else + macosx_init_exception_handler(1); +# endif # endif # ifdef NEED_SIGACTION { diff --git a/src/mzscheme/gc2/vm_osx.c b/src/mzscheme/gc2/vm_osx.c index 6d01b12103..4cf8233177 100644 --- a/src/mzscheme/gc2/vm_osx.c +++ b/src/mzscheme/gc2/vm_osx.c @@ -35,6 +35,64 @@ static int designate_modified(void *p); int designate_modified(void *p); #endif +#if defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC) +typedef struct OSXThreadData { + struct OSXThreadData *next; + mach_port_t thread_port_id; + Thread_Local_Variables *tlvs; +} OSXThreadData; + +/* static const int OSX_THREAD_TABLE_SIZE = 256; */ +#define OSX_THREAD_TABLE_SIZE 256 +static OSXThreadData *osxthreads[OSX_THREAD_TABLE_SIZE]; +static pthread_mutex_t osxthreadsmutex = PTHREAD_MUTEX_INITIALIZER; + +static Thread_Local_Variables *get_mach_thread_tlvs(mach_port_t threadid) { + int index = threadid % OSX_THREAD_TABLE_SIZE; + OSXThreadData *thread; + Thread_Local_Variables *tlvs = NULL; + + pthread_mutex_lock(&osxthreadsmutex); + { + for (thread = osxthreads[index]; thread; thread = thread->next) + { + if (thread->thread_port_id == threadid) { + tlvs = thread->tlvs; + break; + } + } + } + pthread_mutex_unlock(&osxthreadsmutex); + + return tlvs; +} + +static void set_thread_locals_from_mach_thread_id(mach_port_t threadid) { + Thread_Local_Variables *tlvs = get_mach_thread_tlvs(threadid); +#ifdef USE_THREAD_LOCAL + pthread_setspecific(scheme_thread_local_key, tlvs); +#endif +} + +static void register_mach_thread() { + mach_port_t thread_self = mach_thread_self(); + int index = thread_self % OSX_THREAD_TABLE_SIZE; + OSXThreadData * thread = malloc(sizeof(OSXThreadData)); + + thread->thread_port_id = thread_self; + thread->tlvs = scheme_get_thread_local_variables(); + + /* PUSH thread record onto osxthreads datastructure */ + pthread_mutex_lock(&osxthreadsmutex); + { + thread->next = osxthreads[index]; + osxthreads[index] = thread; + } + pthread_mutex_unlock(&osxthreadsmutex); +} + +#endif + #if defined(__POWERPC__) # define ARCH_thread_state_t ppc_thread_state_t # define ARCH_THREAD_STATE PPC_THREAD_STATE @@ -227,6 +285,11 @@ kern_return_t GC_catch_exception_raise(mach_port_t port, &exc_state_count); p = (void *)exc_state.__faultvaddr; #endif + +#if defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC) + set_thread_locals_from_mach_thread_id(thread_port); +#endif + if (designate_modified(p)) return KERN_SUCCESS; else @@ -306,14 +369,22 @@ void GC_attach_current_thread_exceptions_to_handler() GCPRINT(GCOUTF, "Couldn't set exception ports: %s\n", mach_error_string(retval)); abort(); } +#if defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC) + register_mach_thread(); +#endif } /* this initializes the subsystem (sets the exception port, starts the exception handling thread, etc) */ -static void macosx_init_exception_handler() +static void macosx_init_exception_handler(int isMASTERGC) { kern_return_t retval; + if (!isMASTERGC) { + GC_attach_current_thread_exceptions_to_handler(); + return; + } + if(!task_self) task_self = mach_task_self(); /* allocate the port we're going to get exceptions on */ diff --git a/src/mzscheme/src/mzrt.c b/src/mzscheme/src/mzrt.c index 4cdad99dc9..2cf35c6197 100644 --- a/src/mzscheme/src/mzrt.c +++ b/src/mzscheme/src/mzrt.c @@ -196,6 +196,17 @@ mz_proc_thread* mzrt_proc_first_thread_init() { mz_proc_thread* mz_proc_thread_create(mz_proc_thread_start start_proc, void* data) { mz_proc_thread *thread = (mz_proc_thread*)malloc(sizeof(mz_proc_thread)); + pthread_attr_t *attr; + +#ifdef OS_X + pthread_attr_t attr_storage; + attr = &attr_storage; + pthread_attr_init(attr); + pthread_attr_setstacksize(attr, 8*1024*1024); /*8MB*/ +#else + attr = NULL; +#endif + #ifdef MZ_PRECISE_GC mzrt_thread_stub_data *stub_data = (mzrt_thread_stub_data*)malloc(sizeof(mzrt_thread_stub_data)); thread->mbox = pt_mbox_create(); @@ -205,13 +216,13 @@ mz_proc_thread* mz_proc_thread_create(mz_proc_thread_start start_proc, void* dat # ifdef WIN32 thread->threadid = CreateThread(NULL, 0, start_proc, data, 0, NULL); # else - pthread_create(&thread->threadid, NULL, mzrt_thread_stub, stub_data); + pthread_create(&thread->threadid, attr, mzrt_thread_stub, stub_data); # endif #else # ifdef WIN32 thread->threadid = GC_CreateThread(NULL, 0, start_proc, data, 0, NULL); # else - GC_pthread_create(&thread->threadid, NULL, start_proc, data); + GC_pthread_create(&thread->threadid, attr, start_proc, data); # endif #endif return thread;