changeset 10629:12b43beac546

6883880 non-8-byte-aligned mutexes: update needed for solaris_nevada
author Roger A. Faulkner <Roger.Faulkner@Sun.COM>
date Wed, 23 Sep 2009 17:01:56 -0700
parents cddb35f5bfa6
children ccec6d9218ba
files usr/src/lib/libc/port/threads/assfail.c usr/src/lib/libc/port/threads/thr.c usr/src/lib/libc/sparc/threads/asm_subr.s
diffstat 3 files changed, 41 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libc/port/threads/assfail.c	Wed Sep 23 17:30:23 2009 -0600
+++ b/usr/src/lib/libc/port/threads/assfail.c	Wed Sep 23 17:01:56 2009 -0700
@@ -20,12 +20,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include "lint.h"
 #include "thr_uberdata.h"
 
@@ -161,14 +159,19 @@
 void
 lock_error(const mutex_t *mp, const char *who, void *cv, const char *msg)
 {
-	/* take a snapshot of the mutex before it changes (we hope!) */
-	mutex_t mcopy = *mp;
+	mutex_t mcopy;
 	char buf[800];
 	uberdata_t *udp;
 	ulwp_t *self;
 	lwpid_t lwpid;
 	pid_t pid;
 
+	/*
+	 * Take a snapshot of the mutex before it changes (we hope!).
+	 * Use memcpy() rather than 'mcopy = *mp' in case mp is unaligned.
+	 */
+	(void) memcpy(&mcopy, mp, sizeof (mcopy));
+
 	/* avoid recursion deadlock */
 	if ((self = __curthread()) != NULL) {
 		if (assert_thread == self)
@@ -246,8 +249,7 @@
 void
 rwlock_error(const rwlock_t *rp, const char *who, const char *msg)
 {
-	/* take a snapshot of the rwlock before it changes (we hope) */
-	rwlock_t rcopy = *rp;
+	rwlock_t rcopy;
 	uint32_t rwstate;
 	char buf[800];
 	uberdata_t *udp;
@@ -256,6 +258,12 @@
 	pid_t pid;
 	int process;
 
+	/*
+	 * Take a snapshot of the rwlock before it changes (we hope!).
+	 * Use memcpy() rather than 'rcopy = *rp' in case rp is unaligned.
+	 */
+	(void) memcpy(&rcopy, rp, sizeof (rcopy));
+
 	/* avoid recursion deadlock */
 	if ((self = __curthread()) != NULL) {
 		if (assert_thread == self)
--- a/usr/src/lib/libc/port/threads/thr.c	Wed Sep 23 17:30:23 2009 -0600
+++ b/usr/src/lib/libc/port/threads/thr.c	Wed Sep 23 17:01:56 2009 -0700
@@ -1434,6 +1434,26 @@
 	self->ul_adaptive_spin = thread_adaptive_spin;
 	self->ul_queue_spin = thread_queue_spin;
 
+#if defined(__sparc) && !defined(_LP64)
+	if (self->ul_misaligned) {
+		/*
+		 * Tell the kernel to fix up ldx/stx instructions that
+		 * refer to non-8-byte aligned data instead of giving
+		 * the process an alignment trap and generating SIGBUS.
+		 *
+		 * Programs compiled for 32-bit sparc with the Studio SS12
+		 * compiler get this done for them automatically (in _init()).
+		 * We do it here for the benefit of programs compiled with
+		 * other compilers, like gcc.
+		 *
+		 * This is necessary for the _THREAD_LOCKS_MISALIGNED=1
+		 * environment variable horrible hack to work.
+		 */
+		extern void _do_fix_align(void);
+		_do_fix_align();
+	}
+#endif
+
 	/*
 	 * When we have initialized the primary link map, inform
 	 * the dynamic linker about our interface functions.
--- a/usr/src/lib/libc/sparc/threads/asm_subr.s	Wed Sep 23 17:30:23 2009 -0600
+++ b/usr/src/lib/libc/sparc/threads/asm_subr.s	Wed Sep 23 17:01:56 2009 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -82,6 +82,11 @@
 	retl
 	ta	ST_GETPSR
 	SET_SIZE(_getpsr)
+
+	ENTRY(_do_fix_align)
+	retl
+	ta	ST_FIX_ALIGN
+	SET_SIZE(_do_fix_align)
 #endif
 
 	ENTRY(_getfsr)