Changeset 203f4c3 in mainline for generic/src/synch/waitq.c
- Timestamp:
- 2006-04-09T14:14:49Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 016acbe
- Parents:
- fe04594
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/synch/waitq.c
rfe04594 r203f4c3 40 40 #include <adt/list.h> 41 41 42 static void waitq_timeouted_sleep(void *data); 43 42 44 /** Initialize wait queue 43 45 * … … 65 67 * @param data Pointer to the thread that called waitq_sleep_timeout(). 66 68 */ 67 void waitq_ interrupted_sleep(void *data)69 void waitq_timeouted_sleep(void *data) 68 70 { 69 71 thread_t *t = (thread_t *) data; … … 101 103 } 102 104 103 /** Sleep until either wakeup or timeout occurs 105 /** Interrupt sleeping thread. 106 * 107 * This routine attempts to interrupt a thread from its sleep in a waitqueue. 108 * If the thread is not found sleeping, no action is taken. 109 * 110 * @param t Thread to be interrupted. 111 */ 112 void waitq_interrupt_sleep(thread_t *t) 113 { 114 waitq_t *wq; 115 bool do_wakeup = false; 116 ipl_t ipl; 117 118 ipl = interrupts_disable(); 119 spinlock_lock(&threads_lock); 120 if (!list_member(&t->threads_link, &threads_head)) 121 goto out; 122 123 grab_locks: 124 spinlock_lock(&t->lock); 125 if ((wq = t->sleep_queue)) { /* assignment */ 126 if (!spinlock_trylock(&wq->lock)) { 127 spinlock_unlock(&t->lock); 128 goto grab_locks; /* avoid deadlock */ 129 } 130 131 list_remove(&t->wq_link); 132 t->saved_context = t->sleep_interruption_context; 133 do_wakeup = true; 134 135 spinlock_unlock(&wq->lock); 136 t->sleep_queue = NULL; 137 } 138 spinlock_unlock(&t->lock); 139 140 if (do_wakeup) 141 thread_ready(t); 142 143 out: 144 spinlock_unlock(&threads_lock); 145 interrupts_restore(ipl); 146 } 147 148 149 /** Sleep until either wakeup, timeout or interruption occurs 104 150 * 105 151 * This is a sleep implementation which allows itself to be … … 131 177 * 132 178 * ESYNCH_TIMEOUT means that the sleep timed out. 179 * 180 * ESYNCH_INTERRUPTED means that somebody interrupted the sleeping thread. 133 181 * 134 182 * ESYNCH_OK_ATOMIC means that the sleep succeeded and that there was … … 179 227 } 180 228 } 181 182 229 183 230 /* … … 185 232 */ 186 233 spinlock_lock(&THREAD->lock); 234 235 /* 236 * Set context that will be restored if the sleep 237 * of this thread is ever interrupted. 238 */ 239 if (!context_save(&THREAD->sleep_interruption_context)) { 240 /* Short emulation of scheduler() return code. */ 241 spinlock_unlock(&THREAD->lock); 242 interrupts_restore(ipl); 243 return ESYNCH_INTERRUPTED; 244 } 245 187 246 if (usec) { 188 247 /* We use the timeout variant. */ 189 248 if (!context_save(&THREAD->sleep_timeout_context)) { 190 /* 191 * Short emulation of scheduler() return code. 192 */ 249 /* Short emulation of scheduler() return code. */ 193 250 spinlock_unlock(&THREAD->lock); 194 251 interrupts_restore(ipl); … … 196 253 } 197 254 THREAD->timeout_pending = true; 198 timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_ interrupted_sleep, THREAD);255 timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_timeouted_sleep, THREAD); 199 256 } 200 257
Note:
See TracChangeset
for help on using the changeset viewer.