Subversion Repositories HelenOS

Rev

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

Rev 2087 Rev 2089
Line 47... Line 47...
47
#include <synch/spinlock.h>
47
#include <synch/spinlock.h>
48
#include <proc/thread.h>
48
#include <proc/thread.h>
49
#include <proc/scheduler.h>
49
#include <proc/scheduler.h>
50
#include <arch/asm.h>
50
#include <arch/asm.h>
51
#include <arch/types.h>
51
#include <arch/types.h>
52
#include <typedefs.h>
-
 
53
#include <time/timeout.h>
52
#include <time/timeout.h>
54
#include <arch.h>
53
#include <arch.h>
55
#include <context.h>
54
#include <context.h>
56
#include <adt/list.h>
55
#include <adt/list.h>
57
 
56
 
Line 115... Line 114...
115
 
114
 
116
out:
115
out:
117
    spinlock_unlock(&threads_lock);
116
    spinlock_unlock(&threads_lock);
118
}
117
}
119
 
118
 
120
/** Interrupt sleeping thread.
-
 
121
 *
-
 
122
 * This routine attempts to interrupt a thread from its sleep in a waitqueue.
-
 
123
 * If the thread is not found sleeping, no action is taken.
-
 
124
 *
-
 
125
 * @param t Thread to be interrupted.
-
 
126
 */
-
 
127
void waitq_interrupt_sleep(thread_t *t)
-
 
128
{
-
 
129
    waitq_t *wq;
-
 
130
    bool do_wakeup = false;
-
 
131
    ipl_t ipl;
-
 
132
 
-
 
133
    ipl = interrupts_disable();
-
 
134
    spinlock_lock(&threads_lock);
-
 
135
    if (!thread_exists(t))
-
 
136
        goto out;
-
 
137
 
-
 
138
grab_locks:
-
 
139
    spinlock_lock(&t->lock);
-
 
140
    if ((wq = t->sleep_queue)) {        /* assignment */
-
 
141
        if (!(t->sleep_interruptible)) {
-
 
142
            /*
-
 
143
             * The sleep cannot be interrupted.
-
 
144
             */
-
 
145
            spinlock_unlock(&t->lock);
-
 
146
            goto out;
-
 
147
        }
-
 
148
           
-
 
149
        if (!spinlock_trylock(&wq->lock)) {
-
 
150
            spinlock_unlock(&t->lock);
-
 
151
            goto grab_locks;    /* avoid deadlock */
-
 
152
        }
-
 
153
 
-
 
154
        if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
-
 
155
            t->timeout_pending = false;
-
 
156
 
-
 
157
        list_remove(&t->wq_link);
-
 
158
        t->saved_context = t->sleep_interruption_context;
-
 
159
        do_wakeup = true;
-
 
160
        t->sleep_queue = NULL;
-
 
161
        spinlock_unlock(&wq->lock);
-
 
162
    }
-
 
163
    spinlock_unlock(&t->lock);
-
 
164
 
-
 
165
    if (do_wakeup)
-
 
166
        thread_ready(t);
-
 
167
 
-
 
168
out:
-
 
169
    spinlock_unlock(&threads_lock);
-
 
170
    interrupts_restore(ipl);
-
 
171
}
-
 
172
 
119
 
173
/** Sleep until either wakeup, timeout or interruption occurs
120
/** Sleep until either wakeup, timeout or interruption occurs
174
 *
121
 *
175
 * This is a sleep implementation which allows itself to time out or to be
122
 * This is a sleep implementation which allows itself to time out or to be
176
 * interrupted from the sleep, restoring a failover context.
123
 * interrupted from the sleep, restoring a failover context.
Line 423... Line 370...
423
    /*
370
    /*
424
     * Lock the thread prior to removing it from the wq.
371
     * Lock the thread prior to removing it from the wq.
425
     * This is not necessary because of mutual exclusion
372
     * This is not necessary because of mutual exclusion
426
     * (the link belongs to the wait queue), but because
373
     * (the link belongs to the wait queue), but because
427
     * of synchronization with waitq_timeouted_sleep()
374
     * of synchronization with waitq_timeouted_sleep()
428
     * and waitq_interrupt_sleep().
375
     * and thread_interrupt_sleep().
429
     *
376
     *
430
     * In order for these two functions to work, the following
377
     * In order for these two functions to work, the following
431
     * invariant must hold:
378
     * invariant must hold:
432
     *
379
     *
433
     * t->sleep_queue != NULL <=> t sleeps in a wait queue
380
     * t->sleep_queue != NULL <=> t sleeps in a wait queue