You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2022/03/25 14:34:47 UTC

[GitHub] [incubator-nuttx] masayuki2009 commented on a change in pull request #5731: arch/risc-v: Improve speed of context switch

masayuki2009 commented on a change in pull request #5731:
URL: https://github.com/apache/incubator-nuttx/pull/5731#discussion_r835328175



##########
File path: arch/risc-v/src/common/riscv_schedulesigaction.c
##########
@@ -265,55 +283,80 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  tcb->xcp.sigdeliver        = (void *)sigdeliver;
-                  tcb->xcp.saved_epc         = tcb->xcp.regs[REG_EPC];
-                  tcb->xcp.saved_int_ctx     = tcb->xcp.regs[REG_INT_CTX];
+                  tcb->xcp.sigdeliver = sigdeliver;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  We must already be in privileged thread mode
                    * to be here.
                    */
 
-                  tcb->xcp.regs[REG_EPC]      = (uintptr_t)riscv_sigdeliver;
+                  /* Save the current register context location */
+
+                  tcb->xcp.saved_regs = tcb->xcp.regs;
+
+                  /* Duplicate the register context.  These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.regs = (uintptr_t *)((uintptr_t)tcb->xcp.regs -
+                                                 XCPTCONTEXT_SIZE);
 
-                  int_ctx                     = tcb->xcp.regs[REG_INT_CTX];
-                  int_ctx                    &= ~MSTATUS_MPIE;
+                  memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
+                         XCPTCONTEXT_SIZE);
 
+                  tcb->xcp.regs[REG_SP]      = (uintptr_t)tcb->xcp.regs +
+                                                 XCPTCONTEXT_SIZE;
+
+                  tcb->xcp.regs[REG_EPC]     = (uintptr_t)riscv_sigdeliver;
+                  int_ctx                    = tcb->xcp.regs[REG_INT_CTX];
+                  int_ctx                   &= ~MSTATUS_MPIE;
+#ifdef CONFIG_BUILD_PROTECTED
+                  int_ctx                   |= MSTATUS_MPPM;
+#endif
                   tcb->xcp.regs[REG_INT_CTX] = int_ctx;
                 }
               else
                 {
                   /* tcb is running on the same CPU */
 
-                  /* Save the return EPC and STATUS registers.  These will be
+                  /* Save the context registers.  These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.sigdeliver = (void *)sigdeliver;
+
+                  tcb->xcp.saved_regs = (uintptr_t *)CURRENT_REGS;
+
+                  /* Duplicate the register context.  These will be
                    * restored by the signal trampoline after the signal has
                    * been delivered.
                    */
 
-                  tcb->xcp.sigdeliver       = (void *)sigdeliver;
-                  tcb->xcp.saved_epc        = CURRENT_REGS[REG_EPC];
-                  tcb->xcp.saved_int_ctx    = CURRENT_REGS[REG_INT_CTX];
+                  CURRENT_REGS = (uintptr_t *)((uintptr_t)CURRENT_REGS -
+                                                XCPTCONTEXT_SIZE);
+
+                  memcpy((uintptr_t *)CURRENT_REGS, tcb->xcp.saved_regs,
+                         XCPTCONTEXT_SIZE);
+
+                  CURRENT_REGS[REG_SP] = (uintptr_t)CURRENT_REGS +
+                                           XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  The kernel-space trampoline must run in
                    * privileged thread mode.
                    */
 
-                  CURRENT_REGS[REG_EPC]     = (uintptr_t)riscv_sigdeliver;
+                  CURRENT_REGS[REG_EPC] = (uintptr_t)riscv_sigdeliver;
 

Review comment:
       The above line is a style change. (just remove spaces).
   

##########
File path: arch/risc-v/src/common/riscv_schedulesigaction.c
##########
@@ -265,55 +283,80 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  tcb->xcp.sigdeliver        = (void *)sigdeliver;
-                  tcb->xcp.saved_epc         = tcb->xcp.regs[REG_EPC];
-                  tcb->xcp.saved_int_ctx     = tcb->xcp.regs[REG_INT_CTX];
+                  tcb->xcp.sigdeliver = sigdeliver;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  We must already be in privileged thread mode
                    * to be here.
                    */
 
-                  tcb->xcp.regs[REG_EPC]      = (uintptr_t)riscv_sigdeliver;
+                  /* Save the current register context location */
+
+                  tcb->xcp.saved_regs = tcb->xcp.regs;
+
+                  /* Duplicate the register context.  These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.regs = (uintptr_t *)((uintptr_t)tcb->xcp.regs -
+                                                 XCPTCONTEXT_SIZE);
 
-                  int_ctx                     = tcb->xcp.regs[REG_INT_CTX];
-                  int_ctx                    &= ~MSTATUS_MPIE;
+                  memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
+                         XCPTCONTEXT_SIZE);
 
+                  tcb->xcp.regs[REG_SP]      = (uintptr_t)tcb->xcp.regs +
+                                                 XCPTCONTEXT_SIZE;
+
+                  tcb->xcp.regs[REG_EPC]     = (uintptr_t)riscv_sigdeliver;
+                  int_ctx                    = tcb->xcp.regs[REG_INT_CTX];
+                  int_ctx                   &= ~MSTATUS_MPIE;
+#ifdef CONFIG_BUILD_PROTECTED
+                  int_ctx                   |= MSTATUS_MPPM;
+#endif
                   tcb->xcp.regs[REG_INT_CTX] = int_ctx;
                 }
               else
                 {
                   /* tcb is running on the same CPU */
 
-                  /* Save the return EPC and STATUS registers.  These will be
+                  /* Save the context registers.  These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.sigdeliver = (void *)sigdeliver;
+
+                  tcb->xcp.saved_regs = (uintptr_t *)CURRENT_REGS;
+
+                  /* Duplicate the register context.  These will be
                    * restored by the signal trampoline after the signal has
                    * been delivered.
                    */
 
-                  tcb->xcp.sigdeliver       = (void *)sigdeliver;
-                  tcb->xcp.saved_epc        = CURRENT_REGS[REG_EPC];
-                  tcb->xcp.saved_int_ctx    = CURRENT_REGS[REG_INT_CTX];
+                  CURRENT_REGS = (uintptr_t *)((uintptr_t)CURRENT_REGS -
+                                                XCPTCONTEXT_SIZE);
+
+                  memcpy((uintptr_t *)CURRENT_REGS, tcb->xcp.saved_regs,
+                         XCPTCONTEXT_SIZE);
+
+                  CURRENT_REGS[REG_SP] = (uintptr_t)CURRENT_REGS +
+                                           XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  The kernel-space trampoline must run in
                    * privileged thread mode.
                    */
 
-                  CURRENT_REGS[REG_EPC]     = (uintptr_t)riscv_sigdeliver;
+                  CURRENT_REGS[REG_EPC] = (uintptr_t)riscv_sigdeliver;
 
-                  int_ctx                   = CURRENT_REGS[REG_INT_CTX];
-                  int_ctx                   &= ~MSTATUS_MPIE;
+                  int_ctx               = CURRENT_REGS[REG_INT_CTX];
+                  int_ctx              &= ~MSTATUS_MPIE;
 #ifndef CONFIG_BUILD_FLAT
-                  int_ctx                   |= MSTATUS_MPPM;
+                  int_ctx              |= MSTATUS_MPPM;

Review comment:
       ditto.
   

##########
File path: arch/risc-v/src/common/riscv_schedulesigaction.c
##########
@@ -370,7 +428,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
 
           int_ctx                     = tcb->xcp.regs[REG_INT_CTX];
           int_ctx                    &= ~MSTATUS_MPIE;
-
+#ifdef CONFIG_BUILD_PROTECTED

Review comment:
       ditto
   

##########
File path: arch/risc-v/src/common/riscv_sigdeliver.c
##########
@@ -114,7 +110,7 @@ void riscv_sigdeliver(void)
    */
 
   sinfo("Resuming EPC: %" PRIxREG " INT_CTX: %" PRIxREG "\n",
-        regs[REG_EPC], regs[REG_INT_CTX]);
+          regs[REG_EPC], regs[REG_INT_CTX]);
 

Review comment:
       ditto.
   

##########
File path: arch/risc-v/src/common/riscv_schedulesigaction.c
##########
@@ -170,25 +179,34 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
            * been delivered.
            */
 
-          tcb->xcp.sigdeliver       = sigdeliver;
-          tcb->xcp.saved_epc        = tcb->xcp.regs[REG_EPC];
-          tcb->xcp.saved_int_ctx    = tcb->xcp.regs[REG_INT_CTX];
+          tcb->xcp.sigdeliver = sigdeliver;
 
-          /* Then set up to vector to the trampoline with interrupts
-           * disabled.  We must already be in privileged thread mode to be
-           * here.
+          /* Save the current register context location */
+
+          tcb->xcp.saved_regs = tcb->xcp.regs;
+
+          /* Duplicate the register context.  These will be
+           * restored by the signal trampoline after the signal has been
+           * delivered.
            */
 
-          tcb->xcp.regs[REG_EPC]      = (uintptr_t)riscv_sigdeliver;
+          tcb->xcp.regs = (uintptr_t *)((uintptr_t)tcb->xcp.regs -
+                                         XCPTCONTEXT_SIZE);
+
+          memcpy(tcb->xcp.regs, tcb->xcp.saved_regs, XCPTCONTEXT_SIZE);
 
+          tcb->xcp.regs[REG_SP]       = (uintptr_t)tcb->xcp.regs +
+                                          XCPTCONTEXT_SIZE;
+
+          tcb->xcp.regs[REG_EPC]      = (uintptr_t)riscv_sigdeliver;
           int_ctx                     = tcb->xcp.regs[REG_INT_CTX];
           int_ctx                    &= ~MSTATUS_MPIE;
-
           tcb->xcp.regs[REG_INT_CTX]  = int_ctx;

Review comment:
       The above change is a style change. (just remove a blank line)
   

##########
File path: arch/risc-v/src/common/riscv_schedulesigaction.c
##########
@@ -265,55 +283,80 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
                    * been delivered.
                    */
 
-                  tcb->xcp.sigdeliver        = (void *)sigdeliver;
-                  tcb->xcp.saved_epc         = tcb->xcp.regs[REG_EPC];
-                  tcb->xcp.saved_int_ctx     = tcb->xcp.regs[REG_INT_CTX];
+                  tcb->xcp.sigdeliver = sigdeliver;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  We must already be in privileged thread mode
                    * to be here.
                    */
 
-                  tcb->xcp.regs[REG_EPC]      = (uintptr_t)riscv_sigdeliver;
+                  /* Save the current register context location */
+
+                  tcb->xcp.saved_regs = tcb->xcp.regs;
+
+                  /* Duplicate the register context.  These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.regs = (uintptr_t *)((uintptr_t)tcb->xcp.regs -
+                                                 XCPTCONTEXT_SIZE);
 
-                  int_ctx                     = tcb->xcp.regs[REG_INT_CTX];
-                  int_ctx                    &= ~MSTATUS_MPIE;
+                  memcpy(tcb->xcp.regs, tcb->xcp.saved_regs,
+                         XCPTCONTEXT_SIZE);
 
+                  tcb->xcp.regs[REG_SP]      = (uintptr_t)tcb->xcp.regs +
+                                                 XCPTCONTEXT_SIZE;
+
+                  tcb->xcp.regs[REG_EPC]     = (uintptr_t)riscv_sigdeliver;
+                  int_ctx                    = tcb->xcp.regs[REG_INT_CTX];
+                  int_ctx                   &= ~MSTATUS_MPIE;
+#ifdef CONFIG_BUILD_PROTECTED
+                  int_ctx                   |= MSTATUS_MPPM;
+#endif
                   tcb->xcp.regs[REG_INT_CTX] = int_ctx;
                 }
               else
                 {
                   /* tcb is running on the same CPU */
 
-                  /* Save the return EPC and STATUS registers.  These will be
+                  /* Save the context registers.  These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.sigdeliver = (void *)sigdeliver;
+
+                  tcb->xcp.saved_regs = (uintptr_t *)CURRENT_REGS;
+
+                  /* Duplicate the register context.  These will be
                    * restored by the signal trampoline after the signal has
                    * been delivered.
                    */
 
-                  tcb->xcp.sigdeliver       = (void *)sigdeliver;
-                  tcb->xcp.saved_epc        = CURRENT_REGS[REG_EPC];
-                  tcb->xcp.saved_int_ctx    = CURRENT_REGS[REG_INT_CTX];
+                  CURRENT_REGS = (uintptr_t *)((uintptr_t)CURRENT_REGS -
+                                                XCPTCONTEXT_SIZE);
+
+                  memcpy((uintptr_t *)CURRENT_REGS, tcb->xcp.saved_regs,
+                         XCPTCONTEXT_SIZE);
+
+                  CURRENT_REGS[REG_SP] = (uintptr_t)CURRENT_REGS +
+                                           XCPTCONTEXT_SIZE;
 
                   /* Then set up vector to the trampoline with interrupts
                    * disabled.  The kernel-space trampoline must run in
                    * privileged thread mode.
                    */
 
-                  CURRENT_REGS[REG_EPC]     = (uintptr_t)riscv_sigdeliver;
+                  CURRENT_REGS[REG_EPC] = (uintptr_t)riscv_sigdeliver;
 
-                  int_ctx                   = CURRENT_REGS[REG_INT_CTX];
-                  int_ctx                   &= ~MSTATUS_MPIE;
+                  int_ctx               = CURRENT_REGS[REG_INT_CTX];

Review comment:
       The above lines are style changes. (just remove spaces).
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org