Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libpthread/arch/sh3 First cut at pthreads MD code for sh...
details: https://anonhg.NetBSD.org/src/rev/95440e74de75
branches: trunk
changeset: 555454:95440e74de75
user: uwe <uwe%NetBSD.org@localhost>
date: Tue Nov 18 03:11:41 2003 +0000
description:
First cut at pthreads MD code for sh3. Based on m68k version.
Regression tests still failing: sem, sigalarm.
diffstat:
lib/libpthread/arch/sh3/pthread_switch.S | 435 +++++++++++++++++++++++++++++-
1 files changed, 411 insertions(+), 24 deletions(-)
diffs (truncated from 491 to 300 lines):
diff -r f9189eff1464 -r 95440e74de75 lib/libpthread/arch/sh3/pthread_switch.S
--- a/lib/libpthread/arch/sh3/pthread_switch.S Tue Nov 18 03:07:29 2003 +0000
+++ b/lib/libpthread/arch/sh3/pthread_switch.S Tue Nov 18 03:11:41 2003 +0000
@@ -1,9 +1,12 @@
-/* $NetBSD: pthread_switch.S,v 1.1 2003/06/23 19:34:46 uwe Exp $ */
-
-/*
- * Copyright (c) 2003 Christian P. Groessler
+/* $NetBSD: pthread_switch.S,v 1.2 2003/11/18 03:11:41 uwe Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams and Steve C. Woodford.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,25 +15,31 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
*/
-
#include <machine/asm.h>
#include "assym.h"
+
/*
* This file implements low-level routines that are exported to
* the machine-independent parts of the thread library. The routines are:
@@ -42,10 +51,83 @@
* as well as some utility code used by these routines.
*/
+
+/*
+ * Enter debugger or die with SIGTRAP if "notreached" code is reached
+ */
+#define NOTREACHED trapa #0xc3
+
+
+/*
+ * It would be cumbersome to use ifdef PIC for every call.
+ * These macros try to hide the difference.
+ */
+#ifdef __STDC__
+# define CALL_TARGET(call_l,target_l) .L_ ## target_l ## _ ## call_l
+#else
+# define CALL_TARGET(call_l,target_l) .L_/**/target_l/**/_/**/call_l
+#endif
+
+#ifdef PIC
+#define CALL(r) bsrf r
+
+#define CALL_DATUM(call_l,target_l) \
+CALL_TARGET(call_l,target_l): .long _C_LABEL(target_l) - (call_l+4)
+
+#else /* !PIC */
+#define CALL(r) jsr @r
+
+#define CALL_DATUM(call_l,target_l) \
+CALL_TARGET(call_l,target_l): .long _C_LABEL(target_l)
+
+#endif /* !PIC */
+
+
+/*
+ * To avoid superfluous memory loads, or consuming extra registers
+ * this code makes assumptions that certain constants are small
+ * enough to be used as immediate data in certain instructions or
+ * adressing formats. It is expected that the layout of pthread
+ * internal structure is not going to be changed frequently.
+ */
+#define ASSERT_LONG_DISPLACEMENT_OK(i) .ifgt (i) - 60; .err; .endif
+#define ASSERT_IMMEDIATE_7BIT_OK(i) .ifgt (i) - 127; .err; .endif
+#define ASSERT_IMMEDIATE_8BIT_OK(i) .ifgt (i) - 255; .err; .endif
+
+ASSERT_LONG_DISPLACEMENT_OK(UC_PC)
+ASSERT_LONG_DISPLACEMENT_OK(PT_SPINLOCKS)
+
+ASSERT_IMMEDIATE_7BIT_OK(PT_UC)
+ASSERT_IMMEDIATE_7BIT_OK(PT_TRAPUC)
+
+
/*
* Utility macro to switch to the stack of another thread.
+ * Sets tmp to the thread's ucontext to switch to.
+ * Clobbers r0 and r1.
+ *
+ * *** WARNING ***
+ * STACK_SWITCH is more subtle than it looks. Please go read the extended
+ * comment in the i386 pthread_switch.S file.
*/
-#define STACK_SWITCH(pt,tmp)
+#define STACK_SWITCH(pt,tmp) \
+ mov #PT_TRAPUC, r0 ; \
+ mov.l @(r0,pt), tmp /* check pt_trapuc first */ ; \
+ mov #0, r1 ; \
+ tst tmp, tmp /* pt_trapuc == NULL? */ ; \
+ bf/s 100f /* if not, use it */ ; \
+ mov.l r1, @(r0,pt) /* clear pt_trapuc */ ; \
+ mov #PT_UC, r0 ; \
+ mov.l @(r0,pt), tmp /* else, switch to pt_uc */ ; \
+100: \
+.ifeq STACKSPACE ; \
+ mov tmp, sp ; \
+.else ; \
+ mov tmp, r0 ; \
+ add #STACKSPACE, r0 ; \
+ mov r0, sp ; \
+.endif
+
/*
@@ -57,23 +139,242 @@
* already dealing with spin-preemption or other gunk.
*/
NENTRY(pthread__switch)
+ mov.l r8, @-sp
+ mov.l r9, @-sp
+ sts.l pr, @-sp
+ mov r4, r8 /* self */
+ mov r5, r9 /* next */
+
+ mov.l .L_rnd_ctxsize, r0
+ sub r0, sp /* auto ucontext_t cntx; */
+
+ mov.l CALL_TARGET(11b,_getcontext_u), r0
+11: CALL (r0) /* _getcontext_u(&cntx); */
+ mov sp, r4
+
+ /*
+ * Edit the context so that it continues as if returning from
+ * the _setcontext_u below:
+ */
+ mova _C_LABEL(pthread__switch_return_point), r0
+ mov.l r0, @(UC_PC, sp)
+
+ mov #PT_UC, r0
+ mov.l sp, @(r0, r8) /* self->pt_uc = &cntx; */
+
+ STACK_SWITCH(r9, r4) /* r4 = next->pt_uc; */
+
+ mov.l CALL_TARGET(12b,_setcontext_u), r0
+12: CALL (r0) /* _setcontext_u(next->pt_uc); */
+ nop
+ NOTREACHED
+
+
+ .align 2 /* mova target */
+ALTENTRY(pthread__switch_return_point)
+ /* we're back on the original stack */
+ mov.l .L_rnd_ctxsize, r0
+ add r0, sp /* ditch the ucontext_t */
+ lds.l @sp+, pr
+ mov.l @sp+, r9
rts
- nop
+ mov.l @sp+, r8
+
+
+ .align 2
+CALL_DATUM(11b,_getcontext_u)
+CALL_DATUM(12b,_setcontext_u)
+
+
-ALTENTRY(pthread__switch_return_point)
- rts
+/*
+ * Helper switch code used by pthread__locked_switch() and
+ * pthread__upcall_switch() when they discover spinlock preemption.
+ *
+ * Call with:
+ * r2 = from, r3 = to
+ */
+Lpthread__switch_away_decrement:
+ STACK_SWITCH(r3, r4) /* side effect: r4 = to->pt_uc */
+
+ /*
+ * If we're invoked from the switch-to-next provisions of
+ * pthread__locked_switch or pthread__upcall_switch, there
+ * may be a fake spinlock-count set. If so, we decrement it
+ * once we're no longer using the old stack.
+ */
+ mov.l @(PT_SPINLOCKS, r2), r0
+ mov.l CALL_TARGET(21b,_setcontext_u), r1
+ add #-1, r0 /* --from->pt_spinlocks; */
+21: CALL (r1) /* _setcontext_u(to->pt_uc); */
+ mov.l r0, @(PT_SPINLOCKS, r2)
+ NOTREACHED
+
+ .align 2
+CALL_DATUM(21b,_setcontext_u)
+
+
+
+/*
+ * Helper switch code used by pthread__locked_switch() and
+ * pthread__upcall_switch().
+ *
+ * Call with:
+ * r3 = to
+ */
+Lpthread__switch_away_no_decrement:
+ STACK_SWITCH(r3, r4) /* side effect: r4 = to->pt_uc */
+
+ mov.l CALL_TARGET(31b,_setcontext_u), r1
+31: CALL (r1) /* _setcontext_u(to->pt_uc); */
nop
+ NOTREACHED
+
+ .align 2
+CALL_DATUM(31b,_setcontext_u)
+
+
/*
* void pthread__locked_switch(pthread_t self, pthread_t next, pt_spin_t *lock);
*
* Switch away from a thread that is holding a lock on a queue (to
* prevent being removed from the queue before being switched away).
- *
*/
NENTRY(pthread__locked_switch)
+ mov.l r8, @-sp
+ mov.l r9, @-sp
+ mov.l r10, @-sp
+ sts.l pr, @-sp
+ mov r4, r8 /* self */
+ mov r5, r9 /* next */
+ mov r6, r10 /* lock */
+
+ mov.l .L_rnd_ctxsize, r0
+ sub r0, sp /* auto ucontext_t cntx; */
+
+ mov.l @(PT_SPINLOCKS, r9), r0 /* make sure we get continued */
+ add #1, r0
+ mov.l r0, @(PT_SPINLOCKS, r9) /* ++next->pt_spinlocks */
+
+ mov #PT_UC, r0
+ mov.l sp, @(r0, r8) /* self->pt_uc = &cntx; */
+
+ mov.l CALL_TARGET(41b,_getcontext_u), r0
+41: CALL (r0) /* _getcontext_u(self->pt_uc); */
+ mov sp, r4
+
+ /*
+ * Edit the context so that it continues as if returning from
+ * the _setcontext_u below.
+ */
+ mova Lpthread__locked_switch_return_point, r0
+ mov.l r0, @(UC_PC, sp)
+
+ STACK_SWITCH(r9, r4) /* r4 = next->pt_uc; */
+
+ /*
+ * Check if the original thread was preempted while holding
+ * its queue lock.
+ */
+ mov.l .L_pt_next, r0
+ mov.l @(r0, r8), r3
+ tst r3, r3 /* self->pt_next == NULL? */
+ bt Llocked_no_old_preempt
Home |
Main Index |
Thread Index |
Old Index