[96292] trunk/dports/lang/sbcl/files/patch-osx-10.8.diff

easieste at macports.org easieste at macports.org
Mon Aug 6 22:15:36 PDT 2012


Revision: 96292
          https://trac.macports.org/changeset/96292
Author:   easieste at macports.org
Date:     2012-08-06 22:15:35 -0700 (Mon, 06 Aug 2012)
Log Message:
-----------
lang/sbcl: (currently) unapplied, untested patch for osx-10.8.

Patch needs to be adjusted to fit to Macports source location.

~/work/sbcl$ echo '"1.0.57-macports"' > version.lisp-expr
~/work/sbcl$ sh make.sh --fancy

Added Paths:
-----------
    trunk/dports/lang/sbcl/files/patch-osx-10.8.diff

Added: trunk/dports/lang/sbcl/files/patch-osx-10.8.diff
===================================================================
--- trunk/dports/lang/sbcl/files/patch-osx-10.8.diff	                        (rev 0)
+++ trunk/dports/lang/sbcl/files/patch-osx-10.8.diff	2012-08-07 05:15:35 UTC (rev 96292)
@@ -0,0 +1,205 @@
+# HG changeset patch
+# User Paul Khuong <pvk at pvk.ca>
+# Date 1343858434 14400
+# Node ID 755947db369e40e31a470dadfb12a8d9646d60a4
+# Parent  21dbb1f9c54ef0590aaf0d559137048d3c23ffd9
+Fix threads on Darwin 10.8
+
+ * We used to pun (64-bit) addresses into 32-bit mach_port_name.
+
+ * We used to assume arbitrary 32-bit addresses were always
+   acceptable mach port names.
+
+ * Stop doing that. Instead, allocate small descriptors until one's
+   address is an acceptable port name (inspired by CCL).
+
+ * Also, keep a lock-free free-list of descriptors to skip the previous
+   loop in common cases.
+
+ * There are still some strange issues, but I can't tell if they're new,
+   and they seem preferable to consistently lose-ing when spawning threads.
+
+diff --git a/src/runtime/darwin-os.c b/src/runtime/darwin-os.c
+--- a/src/runtime/darwin-os.c
++++ b/src/runtime/darwin-os.c
+@@ -27,6 +27,8 @@
+ 
+ #ifdef LISP_FEATURE_MACH_EXCEPTION_HANDLER
+ #include <mach/mach.h>
++#include <libkern/OSAtomic.h>
++#include <stdlib.h>
+ #endif
+ 
+ char *
+@@ -96,23 +98,80 @@
+     return mach_exception_handling_thread;
+ }
+ 
++struct exception_port_record
++{
++    struct thread * thread;
++    struct exception_port_record * next;
++};
++
++static OSQueueHead free_records = OS_ATOMIC_QUEUE_INIT;
++
++/* We can't depend on arbitrary addresses to be accepted as mach port
++ * names, particularly not on 64-bit platforms.  Instead, we allocate
++ * records that point to the thread struct, and loop until one is accepted
++ * as a port name.
++ *
++ * Threads are mapped to exception ports with a slot in the thread struct,
++ * and exception ports are casted to records that point to the corresponding
++ * thread.
++ *
++ * The lock-free free-list above is used as a cheap fast path.
++ */
++static mach_port_t
++find_receive_port(struct thread * thread)
++{
++    mach_port_t ret;
++    struct exception_port_record * curr, * to_free = NULL;
++    unsigned long i;
++    for (i = 1;; i++) {
++        curr = OSAtomicDequeue(&free_records, offsetof(struct exception_port_record, next));
++        if (curr == NULL) {
++            curr = calloc(1, sizeof(struct exception_port_record));
++            if (curr == NULL)
++                lose("unable to allocate exception_port_record\n");
++        }
++#ifdef LISP_FEATURE_X86_64
++        if ((mach_port_t)curr != (unsigned long)curr)
++            goto skip;
++#endif
++
++        if (mach_port_allocate_name(current_mach_task,
++                                    MACH_PORT_RIGHT_RECEIVE,
++                                    (mach_port_t)curr))
++            goto skip;
++        curr->thread = thread;
++        ret = (mach_port_t)curr;
++        break;
++        skip:
++        curr->next = to_free;
++        to_free = curr;
++        if ((i % 1024) == 0)
++            FSHOW((stderr, "Looped %lu times trying to allocate an exception port\n"));
++    }
++    while (to_free != NULL) {
++        struct exception_port_record * current = to_free;
++        to_free = to_free->next;
++        free(current);
++    }
++
++    FSHOW((stderr, "Allocated exception port %x for thread %p\n", ret, thread));
++
++    return ret;
++}
++
+ /* tell the kernel that we want EXC_BAD_ACCESS exceptions sent to the
+    exception port (which is being listened to do by the mach
+    exception handling thread). */
+ kern_return_t
+-mach_thread_init(mach_port_t thread_exception_port)
++mach_lisp_thread_init(struct thread * thread)
+ {
+     kern_return_t ret;
+-    mach_port_t current_mach_thread;
++    mach_port_t current_mach_thread, thread_exception_port;
+ 
+     /* allocate a named port for the thread */
+-    FSHOW((stderr, "Allocating mach port %x\n", thread_exception_port));
+-    ret = mach_port_allocate_name(current_mach_task,
+-                                  MACH_PORT_RIGHT_RECEIVE,
+-                                  thread_exception_port);
+-    if (ret) {
+-        lose("mach_port_allocate_name failed with return_code %d\n", ret);
+-    }
++    thread_exception_port
++        = thread->mach_port_name
++        = find_receive_port(thread);
+ 
+     /* establish the right for the thread_exception_port to send messages */
+     ret = mach_port_insert_right(current_mach_task,
+@@ -149,31 +208,24 @@
+ }
+ 
+ kern_return_t
+-mach_lisp_thread_init(struct thread *thread) {
+-    mach_port_t port = (mach_port_t) thread;
++mach_lisp_thread_destroy(struct thread *thread) {
+     kern_return_t ret;
+-    ret = mach_thread_init(port);
+-    thread->mach_port_name = port;
++    mach_port_t port = thread->mach_port_name;
++    FSHOW((stderr, "Deallocating mach port %x\n", port));
++    mach_port_move_member(current_mach_task, port, MACH_PORT_NULL);
++    mach_port_deallocate(current_mach_task, port);
++
++    ret = mach_port_destroy(current_mach_task, port);
++    ((struct exception_port_record*)port)->thread = NULL;
++    OSAtomicEnqueue(&free_records, (void*)port, offsetof(struct exception_port_record, next));
+ 
+     return ret;
+ }
+ 
+-kern_return_t
+-mach_lisp_thread_destroy(struct thread *thread) {
+-    mach_port_t port = (mach_port_t) thread;
+-
+-    FSHOW((stderr, "Deallocating mach port %x\n", port));
+-    mach_port_move_member(current_mach_task, port, MACH_PORT_NULL);
+-    mach_port_deallocate(current_mach_task, port);
+-
+-    return mach_port_destroy(current_mach_task, port);
+-}
+-
+ void
+ setup_mach_exceptions() {
+-    mach_port_t port = (mach_port_t) all_threads;
+     setup_mach_exception_handling_thread();
+-    mach_thread_init(port);
++    mach_lisp_thread_init(all_threads);
+ }
+ 
+ pid_t
+diff --git a/src/runtime/x86-64-darwin-os.c b/src/runtime/x86-64-darwin-os.c
+--- a/src/runtime/x86-64-darwin-os.c
++++ b/src/runtime/x86-64-darwin-os.c
+@@ -325,9 +325,10 @@
+ 
+     os_vm_address_t addr;
+ 
+-    struct thread *th = (struct thread*) exception_port;
++    struct thread *th;
+ 
+     FSHOW((stderr,"/entering catch_exception_raise with exception: %d\n", exception));
++    th = *(struct thread**)exception_port;
+ 
+     switch (exception) {
+ 
+@@ -346,8 +347,6 @@
+                                (thread_state_t)&exception_state,
+                                &exception_state_count);
+         addr = (void*)exception_state.faultvaddr;
+-
+-
+         /* note the os_context hackery here.  When the signal handler returns,
+          * it won't go back to what it was doing ... */
+         if(addr >= CONTROL_STACK_GUARD_PAGE(th) &&
+diff --git a/src/runtime/x86-darwin-os.c b/src/runtime/x86-darwin-os.c
+--- a/src/runtime/x86-darwin-os.c
++++ b/src/runtime/x86-darwin-os.c
+@@ -395,10 +395,10 @@
+     siginfo_t siginfo;
+     kern_return_t ret, dealloc_ret;
+ 
+-    struct thread *th = (struct thread*) exception_port;
++    struct thread *th;
+ 
+     FSHOW((stderr,"/entering catch_exception_raise with exception: %d\n", exception));
+-
++    th = *(struct thread**)exception_port;
+     /* Get state and info */
+     state_count = x86_THREAD_STATE32_COUNT;
+     if ((ret = thread_get_state(thread,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20120806/814aa942/attachment.html>


More information about the macports-changes mailing list