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 <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
Masayuki Ishikawa 2020-11-10 11:03:12 +09:00 committed by Xiang Xiao
parent 73d5700183
commit f0bf2143f6
1 changed files with 13 additions and 0 deletions

View File

@ -137,6 +137,15 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
} }
else 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 /* We found the join info structure. Increment for the reference
* to the join structure that we have. This will keep things * to the join structure that we have. This will keep things
* stable for we have to do * stable for we have to do
@ -211,6 +220,10 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
sched_unlock(); sched_unlock();
#ifdef CONFIG_SMP
leave_critical_section(flags);
#endif
/* Release our reference to the join structure and, if the reference /* Release our reference to the join structure and, if the reference
* count decrements to zero, deallocate the join structure. * count decrements to zero, deallocate the join structure.
*/ */