Changeset 203f4c3 in mainline for generic/src/synch/waitq.c


Ignore:
Timestamp:
2006-04-09T14:14:49Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
016acbe
Parents:
fe04594
Message:

Sleeping in a wait queue can be now interrupted with
waitq_interrupt_sleep().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • generic/src/synch/waitq.c

    rfe04594 r203f4c3  
    4040#include <adt/list.h>
    4141
     42static void waitq_timeouted_sleep(void *data);
     43
    4244/** Initialize wait queue
    4345 *
     
    6567 * @param data Pointer to the thread that called waitq_sleep_timeout().
    6668 */
    67 void waitq_interrupted_sleep(void *data)
     69void waitq_timeouted_sleep(void *data)
    6870{
    6971        thread_t *t = (thread_t *) data;
     
    101103}
    102104
    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 */
     112void 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
     123grab_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
     143out:
     144        spinlock_unlock(&threads_lock);
     145        interrupts_restore(ipl);
     146}
     147
     148
     149/** Sleep until either wakeup, timeout or interruption occurs
    104150 *
    105151 * This is a sleep implementation which allows itself to be
     
    131177 *
    132178 * ESYNCH_TIMEOUT means that the sleep timed out.
     179 *
     180 * ESYNCH_INTERRUPTED means that somebody interrupted the sleeping thread.
    133181 *
    134182 * ESYNCH_OK_ATOMIC means that the sleep succeeded and that there was
     
    179227                }
    180228        }
    181 
    182229       
    183230        /*
     
    185232         */
    186233        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
    187246        if (usec) {
    188247                /* We use the timeout variant. */
    189248                if (!context_save(&THREAD->sleep_timeout_context)) {
    190                         /*
    191                          * Short emulation of scheduler() return code.
    192                          */
     249                        /* Short emulation of scheduler() return code. */
    193250                        spinlock_unlock(&THREAD->lock);
    194251                        interrupts_restore(ipl);
     
    196253                }
    197254                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);
    199256        }
    200257
Note: See TracChangeset for help on using the changeset viewer.