mirror of
https://github.com/apache/nuttx.git
synced 2026-08-17 17:43:22 +08:00
sched/pthread: fix race condition on pthread_cond_wait()
pthread_cond_wait() should be an atomic operation in the mutex lock/unlock.
Since the sched_lock() has been wrongly deleted in the previous commit,
the context switch will occurred after the mutex was unlocked:
--------------------------------------------------------------------
Task1(Priority 100) | Task2(Priority 101)
|
pthread_mutex_lock(mutex); |
| |
pthread_cond_wait(cond, mutex) |
| | |
| | |
| ->enter_critical_section() |
| ->pthread_mutex_give(mutex) | ----> pthread_mutex_lock(mutex); // contex switch to high priority task
| | pthread_cond_signal(cond); // signal before wait
| | <---- pthread_mutex_unlock(mutex); // switch back to original task
| ->pthread_sem_take(cond->sem)| // try to wait the signal, Deadlock.
| ->leave_critical_section() |
|
| ->pthread_mutex_take(mutex) |
| |
pthread_mutex_lock(mutex); |
---------------------------------------------------------------------
This PR will bring back sched_lock()/sched_unlock() to avoid context switch to ensure atomicity
Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
@@ -94,6 +94,7 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex)
|
||||
sinfo("Give up mutex / take cond\n");
|
||||
|
||||
flags = enter_critical_section();
|
||||
sched_lock();
|
||||
mutex->pid = INVALID_PROCESS_ID;
|
||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||
mflags = mutex->flags;
|
||||
@@ -116,6 +117,7 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex)
|
||||
ret = status;
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Reacquire the mutex.
|
||||
|
||||
Reference in New Issue
Block a user