Rev 1 | Rev 25 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1 | Rev 15 | ||
---|---|---|---|
Line 127... | Line 127... | ||
127 | * This is an important fix for the race condition between |
127 | * This is an important fix for the race condition between |
128 | * a delayed timeout and a next call to waitq_sleep_timeout(). |
128 | * a delayed timeout and a next call to waitq_sleep_timeout(). |
129 | * Simply, the thread is not allowed to go to sleep if |
129 | * Simply, the thread is not allowed to go to sleep if |
130 | * there are timeouts in progress. |
130 | * there are timeouts in progress. |
131 | */ |
131 | */ |
132 | spinlock_lock(&the->thread->lock); |
132 | spinlock_lock(&THREAD->lock); |
133 | if (the->thread->timeout_pending) { |
133 | if (THREAD->timeout_pending) { |
134 | spinlock_unlock(&the->thread->lock); |
134 | spinlock_unlock(&THREAD->lock); |
135 | cpu_priority_restore(pri); |
135 | cpu_priority_restore(pri); |
136 | goto restart; |
136 | goto restart; |
137 | } |
137 | } |
138 | spinlock_unlock(&the->thread->lock); |
138 | spinlock_unlock(&THREAD->lock); |
139 | 139 | ||
140 | spinlock_lock(&wq->lock); |
140 | spinlock_lock(&wq->lock); |
141 | 141 | ||
142 | /* checks whether to go to sleep at all */ |
142 | /* checks whether to go to sleep at all */ |
143 | if (wq->missed_wakeups) { |
143 | if (wq->missed_wakeups) { |
Line 157... | Line 157... | ||
157 | 157 | ||
158 | 158 | ||
159 | /* |
159 | /* |
160 | * Now we are firmly decided to go to sleep. |
160 | * Now we are firmly decided to go to sleep. |
161 | */ |
161 | */ |
162 | spinlock_lock(&the->thread->lock); |
162 | spinlock_lock(&THREAD->lock); |
163 | if (usec) { |
163 | if (usec) { |
164 | /* We use the timeout variant. */ |
164 | /* We use the timeout variant. */ |
165 | if (!context_save(&the->thread->sleep_timeout_context)) { |
165 | if (!context_save(&THREAD->sleep_timeout_context)) { |
166 | /* |
166 | /* |
167 | * Short emulation of scheduler() return code. |
167 | * Short emulation of scheduler() return code. |
168 | */ |
168 | */ |
169 | spinlock_unlock(&the->thread->lock); |
169 | spinlock_unlock(&THREAD->lock); |
170 | cpu_priority_restore(pri); |
170 | cpu_priority_restore(pri); |
171 | return ESYNCH_TIMEOUT; |
171 | return ESYNCH_TIMEOUT; |
172 | } |
172 | } |
173 | the->thread->timeout_pending = 1; |
173 | THREAD->timeout_pending = 1; |
174 | timeout_register(&the->thread->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, the->thread); |
174 | timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, THREAD); |
175 | } |
175 | } |
176 | 176 | ||
177 | list_append(&the->thread->wq_link, &wq->head); |
177 | list_append(&THREAD->wq_link, &wq->head); |
178 | 178 | ||
179 | /* |
179 | /* |
180 | * Suspend execution. |
180 | * Suspend execution. |
181 | */ |
181 | */ |
182 | the->thread->state = Sleeping; |
182 | THREAD->state = Sleeping; |
183 | the->thread->sleep_queue = wq; |
183 | THREAD->sleep_queue = wq; |
184 | 184 | ||
185 | spinlock_unlock(&the->thread->lock); |
185 | spinlock_unlock(&THREAD->lock); |
186 | 186 | ||
187 | scheduler(); /* wq->lock is released in scheduler_separated_stack() */ |
187 | scheduler(); /* wq->lock is released in scheduler_separated_stack() */ |
188 | cpu_priority_restore(pri); |
188 | cpu_priority_restore(pri); |
189 | 189 | ||
190 | return ESYNCH_OK_BLOCKED; |
190 | return ESYNCH_OK_BLOCKED; |