You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2020/11/13 06:38:50 UTC

[incubator-nuttx] 02/03: sched: pthread: Fix pthread_join() for SMP

This is an automated email from the ASF dual-hosted git repository.

masayuki pushed a commit to branch releases/10.0
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit f93152a867b16e46c63d38cda60c7741c041a6ec
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Tue Nov 10 11:03:12 2020 +0900

    sched: pthread: Fix pthread_join() for SMP
    
    Summary:
    - I noticed 'pthread_rwlock test' in ostest sometimes stops
    - This issue happened with spresense:wifi_smp (NCPUS=4) and sim:smp
    - Finally, I found an issue in pthread_join()
    - In pthread_join(), sched_lock() is used to avoid pre-emption
    - However, this is not enough for SMP
    - Because another CPU would continue the pthread and exit sequences
    - So we need to protect it with a critical section
    
    Impact:
    - Affect SMP only
    
    Testing:
    - Tested with ostest with the following configurations
    - spresnese:smp
    - spresense:wifi_smp (NCPUS=2, NCPUS=4)
    - sabre-6quad:smp (QEMU)
    - esp32-core:smp (QEMU)
    - maix-bit:smp (QEMU)
    - sim:smp
    - lc823450-xgevk:rndis
    
    Signed-off-by: Masayuki Ishikawa <Ma...@jp.sony.com>
---
 sched/pthread/pthread_join.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/sched/pthread/pthread_join.c b/sched/pthread/pthread_join.c
index 994bc7d..328708b 100644
--- a/sched/pthread/pthread_join.c
+++ b/sched/pthread/pthread_join.c
@@ -137,6 +137,15 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
     }
   else
     {
+      /* NOTE: sched_lock() is not enough for SMP
+       * because another CPU would continue the pthread and exit
+       * sequences so need to protect it with a critical section
+       */
+
+#ifdef CONFIG_SMP
+      irqstate_t flags = enter_critical_section();
+#endif
+
       /* We found the join info structure.  Increment for the reference
        * to the join structure that we have.  This will keep things
        * stable for we have to do
@@ -211,6 +220,10 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
 
       sched_unlock();
 
+#ifdef CONFIG_SMP
+      leave_critical_section(flags);
+#endif
+
       /* Release our reference to the join structure and, if the reference
        * count decrements to zero, deallocate the join structure.
        */