Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/synch/condvar.c

    rcc106e4 r9d58539  
    3838#include <synch/condvar.h>
    3939#include <synch/mutex.h>
    40 #include <synch/spinlock.h>
    4140#include <synch/waitq.h>
    4241#include <arch.h>
     
    102101}
    103102
    104 /** Wait for the condition to become true with a locked spinlock.
    105  *
    106  * The function is not aware of irq_spinlock. Therefore do not even
    107  * try passing irq_spinlock_t to it. Use _condvar_wait_timeout_irq_spinlock()
    108  * instead.
    109  *
    110  * @param cv            Condition variable.
    111  * @param lock          Locked spinlock.
    112  * @param usec          Timeout value in microseconds.
    113  * @param flags         Select mode of operation.
    114  *
    115  * For exact description of meaning of possible combinations of usec and flags,
    116  * see comment for waitq_sleep_timeout().  Note that when
    117  * SYNCH_FLAGS_NON_BLOCKING is specified here, ESYNCH_WOULD_BLOCK is always
    118  * returned.
    119  *
    120  * @return See comment for waitq_sleep_timeout().
    121  */
    122 int _condvar_wait_timeout_spinlock_impl(condvar_t *cv, spinlock_t *lock,
    123         uint32_t usec, int flags)
    124 {
    125         int rc;
    126         ipl_t ipl;
    127        
    128         ipl = waitq_sleep_prepare(&cv->wq);
    129 
    130         spinlock_unlock(lock);
    131 
    132         cv->wq.missed_wakeups = 0;      /* Enforce blocking. */
    133         rc = waitq_sleep_timeout_unsafe(&cv->wq, usec, flags);
    134 
    135         waitq_sleep_finish(&cv->wq, rc, ipl);
    136        
    137         spinlock_lock(lock);
    138        
    139         return rc;
    140 }
    141 
    142 /** Wait for the condition to become true with a locked irq spinlock.
    143  *
    144  * @param cv            Condition variable.
    145  * @param lock          Locked irq spinlock.
    146  * @param usec          Timeout value in microseconds.
    147  * @param flags         Select mode of operation.
    148  *
    149  * For exact description of meaning of possible combinations of usec and flags,
    150  * see comment for waitq_sleep_timeout().  Note that when
    151  * SYNCH_FLAGS_NON_BLOCKING is specified here, ESYNCH_WOULD_BLOCK is always
    152  * returned.
    153  *
    154  * @return See comment for waitq_sleep_timeout().
    155  */
    156 int _condvar_wait_timeout_irq_spinlock(condvar_t *cv, irq_spinlock_t *irq_lock,
    157         uint32_t usec, int flags)
    158 {
    159         int rc;
    160         /* Save spinlock's state so we can restore it correctly later on. */
    161         ipl_t ipl = irq_lock->ipl;
    162         bool guard = irq_lock->guard;
    163        
    164         irq_lock->guard = false;
    165        
    166         /*
    167          * waitq_prepare() restores interrupts to the current state,
    168          * ie disabled. Therefore, interrupts will remain disabled while
    169          * it spins waiting for a pending timeout handler to complete.
    170          * Although it spins with interrupts disabled there can only
    171          * be a pending timeout if we failed to cancel an imminent
    172          * timeout (on another cpu) during a wakeup. As a result the
    173          * timeout handler is guaranteed to run (it is most likely already
    174          * running) and there is no danger of a deadlock.
    175          */
    176         rc = _condvar_wait_timeout_spinlock(cv, &irq_lock->lock, usec, flags);
    177        
    178         irq_lock->guard = guard;
    179         irq_lock->ipl = ipl;
    180        
    181         return rc;
    182 }
    183 
    184 
    185103/** @}
    186104 */
Note: See TracChangeset for help on using the changeset viewer.