1.0.6.36: ALLOW-WITH-INTERRUPTS and interrupt safe WITH-MUTEX &co
[sbcl.git] / src / runtime / thread.c
index e529c7d..0bc37a2 100644 (file)
 #include <sys/wait.h>
 #endif
 
+#ifdef LISP_FEATURE_MACH_EXCEPTION_HANDLER
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+#include <mach/mach_types.h>
+#endif
+
 #include "runtime.h"
 #include "validate.h"           /* for CONTROL_STACK_SIZE etc */
 #include "alloc.h"
@@ -49,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
@@ -143,6 +150,7 @@ initial_thread_trampoline(struct thread *th)
 
 #ifdef QUEUE_FREEABLE_THREAD_STACKS
 
+static void
 queue_freeable_thread_stack(struct thread *thread_to_be_cleaned_up)
 {
      if (thread_to_be_cleaned_up) {
@@ -312,6 +320,17 @@ new_thread_trampoline(struct thread *th)
     os_invalidate((os_vm_address_t)th->interrupt_data,
                   (sizeof (struct interrupt_data)));
 
+#ifdef LISP_FEATURE_MACH_EXCEPTION_HANDLER
+    FSHOW((stderr, "Deallocating mach port %x\n", THREAD_STRUCT_TO_EXCEPTION_PORT(th)));
+    mach_port_move_member(mach_task_self(),
+                          THREAD_STRUCT_TO_EXCEPTION_PORT(th),
+                          MACH_PORT_NULL);
+    mach_port_deallocate(mach_task_self(),
+                         THREAD_STRUCT_TO_EXCEPTION_PORT(th));
+    mach_port_destroy(mach_task_self(),
+                      THREAD_STRUCT_TO_EXCEPTION_PORT(th));
+#endif
+
 #ifdef QUEUE_FREEABLE_THREAD_STACKS
     queue_freeable_thread_stack(th);
 #elif defined(CREATE_CLEANUP_THREAD)
@@ -443,6 +462,7 @@ create_thread_struct(lispobj initial_function) {
     bind_variable(FREE_INTERRUPT_CONTEXT_INDEX,make_fixnum(0),th);
     bind_variable(INTERRUPT_PENDING, NIL,th);
     bind_variable(INTERRUPTS_ENABLED,T,th);
+    bind_variable(ALLOW_WITH_INTERRUPTS,T,th);
     bind_variable(GC_PENDING,NIL,th);
 #ifdef LISP_FEATURE_SB_THREAD
     bind_variable(STOP_FOR_GC_PENDING,NIL,th);
@@ -461,9 +481,20 @@ create_thread_struct(lispobj initial_function) {
     return th;
 }
 
+#ifdef LISP_FEATURE_MACH_EXCEPTION_HANDLER
+mach_port_t setup_mach_exception_handling_thread();
+kern_return_t mach_thread_init(mach_port_t thread_exception_port);
+
+#endif
+
 void create_initial_thread(lispobj initial_function) {
     struct thread *th=create_thread_struct(initial_function);
     if(th) {
+#ifdef LISP_FEATURE_MACH_EXCEPTION_HANDLER
+        kern_return_t ret;
+
+        setup_mach_exception_handling_thread();
+#endif
         initial_thread_trampoline(th); /* no return */
     } else lose("can't create initial thread\n");
 }
@@ -520,6 +551,7 @@ boolean create_os_thread(struct thread *th,os_thread_t *kid_tid)
         }
         r=0;
     }
+
 #ifdef QUEUE_FREEABLE_THREAD_STACKS
     free_freeable_stacks();
 #endif