use a normal binary semaphore for cond to allow a signal that happens before a cond_wait but after a condition check to be received
This commit is contained in:
parent
c34dc16b1c
commit
fe61771778
|
@ -36,6 +36,8 @@ void oxygen(void)
|
|||
make_water();
|
||||
rxn.h -= 2;
|
||||
rt_mutex_unlock(&rxn.m);
|
||||
/* To reach this point there will always be >= 2 hydrogens in the
|
||||
* cond_wait, so neither of these signals is missed. */
|
||||
rt_cond_signal(&rxn.hdone);
|
||||
rt_cond_signal(&rxn.hdone);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ struct rt_cond
|
|||
|
||||
#define RT_COND_INIT(name) \
|
||||
{ \
|
||||
.sem = RT_SEM_INIT_MAX(name.sem, 0, 0), \
|
||||
.sem = RT_SEM_INIT_BINARY(name.sem), \
|
||||
}
|
||||
|
||||
#define RT_COND(name) struct rt_cond name = RT_COND_INIT(name)
|
||||
|
|
20
src/cond.c
20
src/cond.c
|
@ -11,7 +11,7 @@
|
|||
|
||||
void rt_cond_init(struct rt_cond *cond)
|
||||
{
|
||||
rt_sem_init_max(&cond->sem, 0, 0);
|
||||
rt_sem_init_binary(&cond->sem);
|
||||
}
|
||||
|
||||
void rt_cond_signal(struct rt_cond *cond)
|
||||
|
@ -32,11 +32,17 @@ void rt_cond_wait(struct rt_cond *cond, struct rt_mutex *mutex)
|
|||
* signals from higher priority tasks on the same monitor can see
|
||||
* there is a waiter. */
|
||||
const int value =
|
||||
rt_atomic_fetch_sub(&cond->sem.value, 1, RT_ATOMIC_RELAXED);
|
||||
rt_atomic_fetch_sub(&cond->sem.value, 1, RT_ATOMIC_ACQUIRE);
|
||||
|
||||
(void)value;
|
||||
rt_logf("%s cond wait, new value %d\n", rt_task_name(), value - 1);
|
||||
|
||||
if (value > 0)
|
||||
{
|
||||
/* The condition was signaled after the caller evaluated the predicate,
|
||||
* so let the caller re-evaluate it without releasing the mutex. */
|
||||
return;
|
||||
}
|
||||
|
||||
rt_mutex_unlock(mutex);
|
||||
|
||||
rt_logf("%s cond wait, waiting\n", rt_task_name());
|
||||
|
@ -57,11 +63,15 @@ bool rt_cond_timedwait(struct rt_cond *cond, struct rt_mutex *mutex,
|
|||
{
|
||||
const unsigned long start_tick = rt_tick_count();
|
||||
const int value =
|
||||
rt_atomic_fetch_sub(&cond->sem.value, 1, RT_ATOMIC_RELAXED);
|
||||
rt_atomic_fetch_sub(&cond->sem.value, 1, RT_ATOMIC_ACQUIRE);
|
||||
|
||||
(void)value;
|
||||
rt_logf("%s cond wait, new value %d\n", rt_task_name(), value - 1);
|
||||
|
||||
if (value > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
rt_mutex_unlock(mutex);
|
||||
|
||||
if (ticks == 0)
|
||||
|
|
Loading…
Reference in New Issue