[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