Subversion Repositories HelenOS-historic

Rev

Rev 552 | Rev 615 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 552 Rev 557
Line 31... Line 31...
31
#include <synch/spinlock.h>
31
#include <synch/spinlock.h>
32
#include <proc/thread.h>
32
#include <proc/thread.h>
33
#include <proc/scheduler.h>
33
#include <proc/scheduler.h>
34
#include <arch/asm.h>
34
#include <arch/asm.h>
35
#include <arch/types.h>
35
#include <arch/types.h>
-
 
36
#include <typedefs.h>
36
#include <time/timeout.h>
37
#include <time/timeout.h>
37
#include <arch.h>
38
#include <arch.h>
38
#include <context.h>
39
#include <context.h>
39
#include <list.h>
40
#include <list.h>
40
 
41
 
Line 65... Line 66...
65
 */
66
 */
66
void waitq_interrupted_sleep(void *data)
67
void waitq_interrupted_sleep(void *data)
67
{
68
{
68
    thread_t *t = (thread_t *) data;
69
    thread_t *t = (thread_t *) data;
69
    waitq_t *wq;
70
    waitq_t *wq;
70
    int do_wakeup = 0;
71
    bool do_wakeup = false;
71
 
72
 
72
    spinlock_lock(&threads_lock);
73
    spinlock_lock(&threads_lock);
73
    if (!list_member(&t->threads_link, &threads_head))
74
    if (!list_member(&t->threads_link, &threads_head))
74
        goto out;
75
        goto out;
75
 
76
 
76
grab_locks:
77
grab_locks:
77
    spinlock_lock(&t->lock);
78
    spinlock_lock(&t->lock);
78
    if (wq = t->sleep_queue) {
79
    if (wq = t->sleep_queue) {      /* assignment */
79
        if (!spinlock_trylock(&wq->lock)) {
80
        if (!spinlock_trylock(&wq->lock)) {
80
            spinlock_unlock(&t->lock);
81
            spinlock_unlock(&t->lock);
81
            goto grab_locks; /* avoid deadlock */
82
            goto grab_locks;    /* avoid deadlock */
82
        }
83
        }
83
 
84
 
84
        list_remove(&t->wq_link);
85
        list_remove(&t->wq_link);
85
        t->saved_context = t->sleep_timeout_context;
86
        t->saved_context = t->sleep_timeout_context;
86
        do_wakeup = 1;
87
        do_wakeup = true;
87
       
88
       
88
        spinlock_unlock(&wq->lock);
89
        spinlock_unlock(&wq->lock);
89
        t->sleep_queue = NULL;
90
        t->sleep_queue = NULL;
90
    }
91
    }
91
   
92
   
92
    t->timeout_pending = 0;
93
    t->timeout_pending = false;
93
    spinlock_unlock(&t->lock);
94
    spinlock_unlock(&t->lock);
94
   
95
   
-
 
96
    if (do_wakeup)
95
    if (do_wakeup) thread_ready(t);
97
        thread_ready(t);
96
 
98
 
97
out:
99
out:
98
    spinlock_unlock(&threads_lock);
100
    spinlock_unlock(&threads_lock);
99
}
101
}
100
 
102
 
Line 191... Line 193...
191
            before_thread_runs();
193
            before_thread_runs();
192
            spinlock_unlock(&THREAD->lock);
194
            spinlock_unlock(&THREAD->lock);
193
            interrupts_restore(ipl);
195
            interrupts_restore(ipl);
194
            return ESYNCH_TIMEOUT;
196
            return ESYNCH_TIMEOUT;
195
        }
197
        }
196
        THREAD->timeout_pending = 1;
198
        THREAD->timeout_pending = true;
197
        timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, THREAD);
199
        timeout_register(&THREAD->sleep_timeout, (__u64) usec, waitq_interrupted_sleep, THREAD);
198
    }
200
    }
199
 
201
 
200
    list_append(&THREAD->wq_link, &wq->head);
202
    list_append(&THREAD->wq_link, &wq->head);
201
 
203
 
Line 225... Line 227...
225
 *
227
 *
226
 * @param wq Pointer to wait queue.
228
 * @param wq Pointer to wait queue.
227
 * @param all If this is non-zero, all sleeping threads
229
 * @param all If this is non-zero, all sleeping threads
228
 *        will be woken up and missed count will be zeroed.
230
 *        will be woken up and missed count will be zeroed.
229
 */
231
 */
230
void waitq_wakeup(waitq_t *wq, int all)
232
void waitq_wakeup(waitq_t *wq, bool all)
231
{
233
{
232
    ipl_t ipl;
234
    ipl_t ipl;
233
 
235
 
234
    ipl = interrupts_disable();
236
    ipl = interrupts_disable();
235
    spinlock_lock(&wq->lock);
237
    spinlock_lock(&wq->lock);
Line 248... Line 250...
248
 *
250
 *
249
 * @param wq Pointer to wait queue.
251
 * @param wq Pointer to wait queue.
250
 * @param all If this is non-zero, all sleeping threads
252
 * @param all If this is non-zero, all sleeping threads
251
 *        will be woken up and missed count will be zeroed.
253
 *        will be woken up and missed count will be zeroed.
252
 */
254
 */
253
void _waitq_wakeup_unsafe(waitq_t *wq, int all)
255
void _waitq_wakeup_unsafe(waitq_t *wq, bool all)
254
{
256
{
255
    thread_t *t;
257
    thread_t *t;
256
 
258
 
257
loop:  
259
loop:  
258
    if (list_empty(&wq->head)) {
260
    if (list_empty(&wq->head)) {
259
        wq->missed_wakeups++;
261
        wq->missed_wakeups++;
-
 
262
        if (all)
260
        if (all) wq->missed_wakeups = 0;
263
            wq->missed_wakeups = 0;
261
        return;
264
        return;
262
    }
265
    }
263
 
266
 
264
    t = list_get_instance(wq->head.next, thread_t, wq_link);
267
    t = list_get_instance(wq->head.next, thread_t, wq_link);
265
   
268
   
266
    list_remove(&t->wq_link);
269
    list_remove(&t->wq_link);
267
    spinlock_lock(&t->lock);
270
    spinlock_lock(&t->lock);
268
    if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
271
    if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
269
        t->timeout_pending = 0;
272
        t->timeout_pending = false;
270
    t->sleep_queue = NULL;
273
    t->sleep_queue = NULL;
271
    spinlock_unlock(&t->lock);
274
    spinlock_unlock(&t->lock);
272
 
275
 
273
    thread_ready(t);
276
    thread_ready(t);
274
 
277
 
-
 
278
    if (all)
275
    if (all) goto loop;
279
        goto loop;
276
}
280
}