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 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 | ||