Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sh3/sh3 Fix cpu_switchto() to correctly prepare new...



details:   https://anonhg.NetBSD.org/src/rev/420e1d2a8e95
branches:  trunk
changeset: 555375:420e1d2a8e95
user:      uwe <uwe%NetBSD.org@localhost>
date:      Sun Nov 16 00:07:13 2003 +0000

description:
Fix cpu_switchto() to correctly prepare new lwp before switching to it.
Fixes PR port-sh3/19956.

Big thanks to Christian Limpach <cl@> for pointing this out and
explaning what the fix is.

diffstat:

 sys/arch/sh3/sh3/locore_c.c    |  63 +++++++++++++++++++++++++----------------
 sys/arch/sh3/sh3/locore_subr.S |  19 +++++++++++-
 2 files changed, 55 insertions(+), 27 deletions(-)

diffs (147 lines):

diff -r 58d1a4da957b -r 420e1d2a8e95 sys/arch/sh3/sh3/locore_c.c
--- a/sys/arch/sh3/sh3/locore_c.c       Sat Nov 15 23:47:58 2003 +0000
+++ b/sys/arch/sh3/sh3/locore_c.c       Sun Nov 16 00:07:13 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore_c.c,v 1.6 2003/11/05 01:43:16 uwe Exp $ */
+/*     $NetBSD: locore_c.c,v 1.7 2003/11/16 00:07:13 uwe Exp $ */
 
 /*-
  * Copyright (c) 1996, 1997, 2002 The NetBSD Foundation, Inc.
@@ -111,7 +111,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: locore_c.c,v 1.6 2003/11/05 01:43:16 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore_c.c,v 1.7 2003/11/16 00:07:13 uwe Exp $");
 
 #include "opt_lockdebug.h"
 
@@ -132,6 +132,7 @@
 
 void (*__sh_switch_resume)(struct lwp *);
 struct lwp *cpu_switch_search(struct lwp *);
+struct lwp *cpu_switch_prepare(struct lwp *, struct lwp *);
 void idle(void);
 int want_resched;
 
@@ -143,9 +144,40 @@
 #define        SCHED_UNLOCK_IDLE()     ((void)0)
 #endif
 
+
 /*
- * struct proc *cpu_switch_search(struct proc *oldproc):
- *     Find the highest priority process.
+ * Prepare context switch from oldlwp to newlwp.
+ * This code is shared by cpu_switch and cpu_switchto.
+ */
+struct lwp *
+cpu_switch_prepare(struct lwp *oldlwp, struct lwp *newlwp)
+{
+
+       newlwp->l_stat = LSONPROC;
+
+       if (newlwp != oldlwp) {
+               struct proc *p = newlwp->l_proc;
+
+               curpcb = newlwp->l_md.md_pcb;
+               pmap_activate(newlwp);
+
+               /* Check for Restartable Atomic Sequences. */
+               if (!LIST_EMPTY(&p->p_raslist)) {
+                       caddr_t pc;
+
+                       pc = ras_lookup(p,
+                               (caddr_t)newlwp->l_md.md_regs->tf_spc);
+                       if (pc != (caddr_t) -1)
+                               newlwp->l_md.md_regs->tf_spc = (int) pc;
+               }
+       }
+
+       curlwp = newlwp;
+       return (newlwp);
+}
+
+/*
+ * Find the highest priority lwp and prepare to switching to it.
  */
 struct lwp *
 cpu_switch_search(struct lwp *oldlwp)
@@ -153,7 +185,7 @@
        struct prochd *q;
        struct lwp *l;
 
-       curlwp = 0;
+       curlwp = NULL;
 
        SCHED_LOCK_IDLE();
        while (sched_whichqs == 0) {
@@ -168,26 +200,7 @@
        want_resched = 0;
        SCHED_UNLOCK_IDLE();
 
-       l->l_stat = LSONPROC;
-
-       if (l != oldlwp) {
-               struct proc *p = l->l_proc;
-
-               curpcb = l->l_md.md_pcb;
-               pmap_activate(l);
-
-               /* Check for Restartable Atomic Sequences. */
-               if (!LIST_EMPTY(&p->p_raslist)) {
-                       caddr_t pc;
-
-                       pc = ras_lookup(p, (caddr_t) l->l_md.md_regs->tf_spc);
-                       if (pc != (caddr_t) -1)
-                               l->l_md.md_regs->tf_spc = (int) pc;
-               }
-       }
-       curlwp = l;
-
-       return (l);
+       return (cpu_switch_prepare(oldlwp, l));
 }
 
 /*
diff -r 58d1a4da957b -r 420e1d2a8e95 sys/arch/sh3/sh3/locore_subr.S
--- a/sys/arch/sh3/sh3/locore_subr.S    Sat Nov 15 23:47:58 2003 +0000
+++ b/sys/arch/sh3/sh3/locore_subr.S    Sun Nov 16 00:07:13 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore_subr.S,v 1.14 2003/03/20 17:45:14 tsutsui Exp $ */
+/*     $NetBSD: locore_subr.S,v 1.15 2003/11/16 00:07:13 uwe Exp $     */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -155,15 +155,30 @@
        mov.l   r15,    @-r1
 
        /*
+        * curlwp = NULL;
+        * XXX Is this necessary?  We know we won't go idle.
+        */
+       mov.l   _L.curlwp, r0
+       mov     #0, r1
+       mov.l   r1, @r0
+
+       /* old and new lwps are already in r4, r5 */
+       mov.l   _L.cpu_switch_prepare, r0
+       jsr     @r0
+        nop
+
+       /*
         * Put the incoming LWP in r4 and jump into the middle
         * of cpu_switch(), and let it do the work to restore the
         * incoming LWP's context.
         */
        bra     _L.doswitch
-        mov    r5, r4
+        mov    r0, r4
 
        .align  2
 _L.SFp:                        .long   (L_MD_PCB)
+_L.curlwp:             .long   _C_LABEL(curlwp)
+_L.cpu_switch_prepare: .long   _C_LABEL(cpu_switch_prepare)
 
 #ifdef SH3
 /*



Home | Main Index | Thread Index | Old Index