Rev 2087 | Rev 2109 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2087 | Rev 2089 | ||
---|---|---|---|
Line 51... | Line 51... | ||
51 | #include <cpu.h> |
51 | #include <cpu.h> |
52 | #include <func.h> |
52 | #include <func.h> |
53 | #include <context.h> |
53 | #include <context.h> |
54 | #include <adt/btree.h> |
54 | #include <adt/btree.h> |
55 | #include <adt/list.h> |
55 | #include <adt/list.h> |
56 | #include <typedefs.h> |
- | |
57 | #include <time/clock.h> |
56 | #include <time/clock.h> |
- | 57 | #include <time/timeout.h> |
|
58 | #include <config.h> |
58 | #include <config.h> |
59 | #include <arch/interrupt.h> |
59 | #include <arch/interrupt.h> |
60 | #include <smp/ipi.h> |
60 | #include <smp/ipi.h> |
61 | #include <arch/faddr.h> |
61 | #include <arch/faddr.h> |
62 | #include <atomic.h> |
62 | #include <atomic.h> |
Line 676... | Line 676... | ||
676 | thread_exit(); |
676 | thread_exit(); |
677 | /* Unreachable */ |
677 | /* Unreachable */ |
678 | return 0; |
678 | return 0; |
679 | } |
679 | } |
680 | 680 | ||
- | 681 | /** Interrupt sleeping thread. |
|
- | 682 | * |
|
- | 683 | * This routine attempts to interrupt a thread from its sleep in a waitqueue. |
|
- | 684 | * If the thread is not found sleeping, no action is taken. |
|
- | 685 | * |
|
- | 686 | * @param t Thread to be interrupted. |
|
- | 687 | */ |
|
- | 688 | void thread_interrupt_sleep(thread_t *t) |
|
- | 689 | { |
|
- | 690 | waitq_t *wq; |
|
- | 691 | bool do_wakeup = false; |
|
- | 692 | ipl_t ipl; |
|
- | 693 | ||
- | 694 | ipl = interrupts_disable(); |
|
- | 695 | spinlock_lock(&threads_lock); |
|
- | 696 | if (!thread_exists(t)) |
|
- | 697 | goto out; |
|
- | 698 | ||
- | 699 | grab_locks: |
|
- | 700 | spinlock_lock(&t->lock); |
|
- | 701 | if ((wq = t->sleep_queue)) { /* assignment */ |
|
- | 702 | if (!(t->sleep_interruptible)) { |
|
- | 703 | /* |
|
- | 704 | * The sleep cannot be interrupted. |
|
- | 705 | */ |
|
- | 706 | spinlock_unlock(&t->lock); |
|
- | 707 | goto out; |
|
- | 708 | } |
|
- | 709 | ||
- | 710 | if (!spinlock_trylock(&wq->lock)) { |
|
- | 711 | spinlock_unlock(&t->lock); |
|
- | 712 | goto grab_locks; /* avoid deadlock */ |
|
- | 713 | } |
|
- | 714 | ||
- | 715 | if (t->timeout_pending && timeout_unregister(&t->sleep_timeout)) |
|
- | 716 | t->timeout_pending = false; |
|
- | 717 | ||
- | 718 | list_remove(&t->wq_link); |
|
- | 719 | t->saved_context = t->sleep_interruption_context; |
|
- | 720 | do_wakeup = true; |
|
- | 721 | t->sleep_queue = NULL; |
|
- | 722 | spinlock_unlock(&wq->lock); |
|
- | 723 | } |
|
- | 724 | spinlock_unlock(&t->lock); |
|
- | 725 | ||
- | 726 | if (do_wakeup) |
|
- | 727 | thread_ready(t); |
|
- | 728 | ||
- | 729 | out: |
|
- | 730 | spinlock_unlock(&threads_lock); |
|
- | 731 | interrupts_restore(ipl); |
|
- | 732 | } |
|
- | 733 | ||
681 | /** @} |
734 | /** @} |
682 | */ |
735 | */ |
683 | 736 |