Changes in kernel/generic/src/synch/condvar.c [e88eb48:0b47781] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/synch/condvar.c
re88eb48 r0b47781 48 48 void condvar_initialize(condvar_t *cv) 49 49 { 50 waitq_initialize(&cv->wq);50 *cv = CONDVAR_INITIALIZER(*cv); 51 51 } 52 52 … … 58 58 void condvar_signal(condvar_t *cv) 59 59 { 60 waitq_ wakeup(&cv->wq, WAKEUP_FIRST);60 waitq_signal(&cv->wq); 61 61 } 62 62 … … 68 68 void condvar_broadcast(condvar_t *cv) 69 69 { 70 waitq_wake up(&cv->wq, WAKEUP_ALL);70 waitq_wake_all(&cv->wq); 71 71 } 72 72 … … 76 76 * @param mtx Mutex. 77 77 * @param usec Timeout value in microseconds. 78 * @param flags Select mode of operation.79 *80 * For exact description of meaning of possible combinations of usec and flags,81 * see comment for waitq_sleep_timeout(). Note that when82 * SYNCH_FLAGS_NON_BLOCKING is specified here, EAGAIN is always83 * returned.84 78 * 85 79 * @return See comment for waitq_sleep_timeout(). 86 80 */ 87 errno_t _ condvar_wait_timeout(condvar_t *cv, mutex_t *mtx, uint32_t usec, int flags)81 errno_t __condvar_wait_timeout_mutex(condvar_t *cv, mutex_t *mtx, uint32_t usec) 88 82 { 89 errno_t rc; 90 ipl_t ipl; 91 bool blocked; 83 wait_guard_t guard = waitq_sleep_prepare(&cv->wq); 92 84 93 ipl = waitq_sleep_prepare(&cv->wq);94 85 /* Unlock only after the waitq is locked so we don't miss a wakeup. */ 95 86 mutex_unlock(mtx); 96 87 97 cv->wq.missed_wakeups = 0; /* Enforce blocking. */ 98 rc = waitq_sleep_timeout_unsafe(&cv->wq, usec, flags, &blocked); 99 assert(blocked || rc != EOK); 88 errno_t rc = waitq_sleep_timeout_unsafe(&cv->wq, usec, SYNCH_FLAGS_NON_BLOCKING, guard); 100 89 101 waitq_sleep_finish(&cv->wq, blocked, ipl);102 /* Lock only after releasing the waitq to avoid a possible deadlock. */103 90 mutex_lock(mtx); 104 105 91 return rc; 106 92 } 107 93 108 /** Wait for the condition to become true with a locked spinlock. 109 * 110 * The function is not aware of irq_spinlock. Therefore do not even 111 * try passing irq_spinlock_t to it. Use _condvar_wait_timeout_irq_spinlock() 112 * instead. 113 * 114 * @param cv Condition variable. 115 * @param lock Locked spinlock. 116 * @param usec Timeout value in microseconds. 117 * @param flags Select mode of operation. 118 * 119 * For exact description of meaning of possible combinations of usec and flags, 120 * see comment for waitq_sleep_timeout(). Note that when 121 * SYNCH_FLAGS_NON_BLOCKING is specified here, EAGAIN is always 122 * returned. 123 * 124 * @return See comment for waitq_sleep_timeout(). 125 */ 126 errno_t _condvar_wait_timeout_spinlock_impl(condvar_t *cv, spinlock_t *lock, 127 uint32_t usec, int flags) 94 errno_t __condvar_wait_mutex(condvar_t *cv, mutex_t *mtx) 128 95 { 129 errno_t rc; 130 ipl_t ipl; 131 bool blocked; 96 wait_guard_t guard = waitq_sleep_prepare(&cv->wq); 132 97 133 ipl = waitq_sleep_prepare(&cv->wq); 98 /* Unlock only after the waitq is locked so we don't miss a wakeup. */ 99 mutex_unlock(mtx); 100 101 errno_t rc = waitq_sleep_unsafe(&cv->wq, guard); 102 103 mutex_lock(mtx); 104 return rc; 105 } 106 107 /** Same as __condvar_wait_timeout_mutex(), except for spinlock_t. */ 108 errno_t __condvar_wait_timeout_spinlock(condvar_t *cv, spinlock_t *lock, 109 uint32_t usec) 110 { 111 wait_guard_t guard = waitq_sleep_prepare(&cv->wq); 134 112 135 113 /* Unlock only after the waitq is locked so we don't miss a wakeup. */ 136 114 spinlock_unlock(lock); 137 115 138 cv->wq.missed_wakeups = 0; /* Enforce blocking. */ 139 rc = waitq_sleep_timeout_unsafe(&cv->wq, usec, flags, &blocked); 140 assert(blocked || rc != EOK); 116 errno_t rc = waitq_sleep_timeout_unsafe(&cv->wq, usec, 117 SYNCH_FLAGS_NON_BLOCKING, guard); 141 118 142 waitq_sleep_finish(&cv->wq, blocked, ipl);143 /* Lock only after releasing the waitq to avoid a possible deadlock. */144 119 spinlock_lock(lock); 145 146 120 return rc; 147 121 } 148 122 149 /** Wait for the condition to become true with a locked irq spinlock. 150 * 151 * @param cv Condition variable. 152 * @param lock Locked irq spinlock. 153 * @param usec Timeout value in microseconds. 154 * @param flags Select mode of operation. 155 * 156 * For exact description of meaning of possible combinations of usec and flags, 157 * see comment for waitq_sleep_timeout(). Note that when 158 * SYNCH_FLAGS_NON_BLOCKING is specified here, EAGAIN is always 159 * returned. 160 * 161 * @return See comment for waitq_sleep_timeout(). 162 */163 errno_t _ condvar_wait_timeout_irq_spinlock(condvar_t *cv, irq_spinlock_t *irq_lock,164 uint32_t usec, int flags)123 errno_t __condvar_wait_spinlock(condvar_t *cv, spinlock_t *mtx) 124 { 125 wait_guard_t guard = waitq_sleep_prepare(&cv->wq); 126 127 /* Unlock only after the waitq is locked so we don't miss a wakeup. */ 128 spinlock_unlock(mtx); 129 130 errno_t rc = waitq_sleep_unsafe(&cv->wq, guard); 131 132 spinlock_lock(mtx); 133 return rc; 134 } 135 136 /** Same as __condvar_wait_timeout_mutex(), except for irq_spinlock_t. */ 137 errno_t __condvar_wait_timeout_irq_spinlock(condvar_t *cv, 138 irq_spinlock_t *irq_lock, uint32_t usec) 165 139 { 166 140 errno_t rc; … … 181 155 * running) and there is no danger of a deadlock. 182 156 */ 183 rc = _condvar_wait_timeout_spinlock(cv, &irq_lock->lock, usec, flags); 157 rc = __condvar_wait_timeout_spinlock(cv, &irq_lock->lock, usec); 158 159 irq_lock->guard = guard; 160 irq_lock->ipl = ipl; 161 162 return rc; 163 } 164 165 /** Same as __condvar_wait_mutex(), except for irq_spinlock_t. */ 166 errno_t __condvar_wait_irq_spinlock(condvar_t *cv, irq_spinlock_t *irq_lock) 167 { 168 errno_t rc; 169 /* Save spinlock's state so we can restore it correctly later on. */ 170 ipl_t ipl = irq_lock->ipl; 171 bool guard = irq_lock->guard; 172 173 irq_lock->guard = false; 174 175 rc = __condvar_wait_spinlock(cv, &irq_lock->lock); 184 176 185 177 irq_lock->guard = guard;
Note:
See TracChangeset
for help on using the changeset viewer.