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:
parent
0aa1af7ff1
commit
b9b615b425
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user