Rev 2894 | Rev 2899 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2894 | Rev 2898 | ||
---|---|---|---|
Line 42... | Line 42... | ||
42 | #include <arch.h> |
42 | #include <arch.h> |
43 | 43 | ||
44 | void udebug_stoppable_begin(void) |
44 | void udebug_stoppable_begin(void) |
45 | { |
45 | { |
46 | int nsc; |
46 | int nsc; |
47 | call_t *db_call; |
47 | call_t *db_call, *go_call; |
48 | ipl_t ipl; |
48 | ipl_t ipl; |
49 | 49 | ||
50 | ipl = interrupts_disable(); |
50 | ipl = interrupts_disable(); |
51 | spinlock_lock(&TASK->lock); |
51 | spinlock_lock(&TASK->lock); |
52 | 52 | ||
Line 57... | Line 57... | ||
57 | klog_printf("udebug_stoppable_begin"); |
57 | klog_printf("udebug_stoppable_begin"); |
58 | klog_printf(" - nsc := %d", nsc); |
58 | klog_printf(" - nsc := %d", nsc); |
59 | } |
59 | } |
60 | 60 | ||
61 | if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
61 | if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
- | 62 | /* |
|
- | 63 | * This was the last non-stoppable thread. Reply to |
|
- | 64 | * DEBUG_BEGIN call. |
|
- | 65 | */ |
|
- | 66 | ||
- | 67 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
|
- | 68 | spinlock_lock(&THREAD->debug_lock); |
|
- | 69 | THREAD->debug_stoppable = true; |
|
- | 70 | spinlock_unlock(&THREAD->debug_lock); |
|
- | 71 | ||
62 | TASK->dt_state = UDEBUG_TS_ACTIVE; |
72 | TASK->dt_state = UDEBUG_TS_ACTIVE; |
63 | TASK->debug_begin_call = NULL; |
73 | TASK->debug_begin_call = NULL; |
64 | spinlock_unlock(&TASK->lock); |
74 | spinlock_unlock(&TASK->lock); |
65 | interrupts_restore(ipl); |
75 | interrupts_restore(ipl); |
66 | 76 | ||
67 | IPC_SET_RETVAL(db_call->data, 0); |
77 | IPC_SET_RETVAL(db_call->data, 0); |
68 | klog_printf("udebug_stoppable_begin/ipc_answer"); |
78 | klog_printf("udebug_stoppable_begin/ipc_answer"); |
69 | ipc_answer(&TASK->answerbox, db_call); |
79 | ipc_answer(&TASK->answerbox, db_call); |
- | 80 | ||
- | 81 | } else if (TASK->dt_state == UDEBUG_TS_ACTIVE) { |
|
- | 82 | /* |
|
- | 83 | * Active debugging session |
|
- | 84 | */ |
|
- | 85 | ||
- | 86 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
|
- | 87 | spinlock_lock(&THREAD->debug_lock); |
|
- | 88 | THREAD->debug_stoppable = true; |
|
- | 89 | ||
- | 90 | if (THREAD->debug_stop) { |
|
- | 91 | /* |
|
- | 92 | * Thread was requested to stop - answer go call |
|
- | 93 | */ |
|
- | 94 | ||
- | 95 | /* Make sure nobody takes this call away from us */ |
|
- | 96 | go_call = THREAD->debug_go_call; |
|
- | 97 | THREAD->debug_go_call = NULL; |
|
- | 98 | ||
- | 99 | IPC_SET_RETVAL(go_call->data, 0); |
|
- | 100 | IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP); |
|
- | 101 | ||
- | 102 | THREAD->cur_event = UDEBUG_EVENT_STOP; |
|
- | 103 | spinlock_unlock(&THREAD->debug_lock); |
|
- | 104 | ||
- | 105 | ipc_answer(&TASK->answerbox, go_call); |
|
- | 106 | ||
- | 107 | spinlock_unlock(&TASK->lock); |
|
- | 108 | interrupts_restore(ipl); |
|
- | 109 | } else { |
|
- | 110 | /* |
|
- | 111 | * No stop request - nothing happens. |
|
- | 112 | */ |
|
- | 113 | spinlock_unlock(&THREAD->debug_lock); |
|
- | 114 | spinlock_unlock(&TASK->lock); |
|
- | 115 | interrupts_restore(ipl); |
|
- | 116 | } |
|
70 | } else { |
117 | } else { |
- | 118 | /* |
|
- | 119 | * All other cases - nothing special happens. |
|
- | 120 | */ |
|
- | 121 | ||
- | 122 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
|
- | 123 | spinlock_lock(&THREAD->debug_lock); |
|
- | 124 | THREAD->debug_stoppable = true; |
|
- | 125 | spinlock_unlock(&THREAD->debug_lock); |
|
- | 126 | ||
71 | spinlock_unlock(&TASK->lock); |
127 | spinlock_unlock(&TASK->lock); |
72 | interrupts_restore(ipl); |
128 | interrupts_restore(ipl); |
73 | } |
129 | } |
74 | } |
130 | } |
75 | 131 | ||
Line 79... | Line 135... | ||
79 | 135 | ||
80 | restart: |
136 | restart: |
81 | ipl = interrupts_disable(); |
137 | ipl = interrupts_disable(); |
82 | spinlock_lock(&TASK->lock); |
138 | spinlock_lock(&TASK->lock); |
83 | 139 | ||
- | 140 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
|
- | 141 | spinlock_lock(&THREAD->debug_lock); |
|
- | 142 | ||
- | 143 | if (TASK->dt_state == UDEBUG_TS_ACTIVE) { |
|
- | 144 | klog_printf("udebug_stoppable_end"); |
|
- | 145 | klog_printf("debug_stop=%d", THREAD->debug_stop); |
|
- | 146 | } |
|
- | 147 | ||
84 | if ((TASK->dt_state == UDEBUG_TS_BEGINNING || |
148 | if ((TASK->dt_state == UDEBUG_TS_BEGINNING || |
85 | TASK->dt_state == UDEBUG_TS_ACTIVE) && |
149 | TASK->dt_state == UDEBUG_TS_ACTIVE) && |
86 | THREAD->debug_stop == true) { |
150 | THREAD->debug_stop == true) { |
87 | TASK->debug_begin_call = NULL; |
151 | TASK->debug_begin_call = NULL; |
- | 152 | spinlock_unlock(&THREAD->debug_lock); |
|
88 | spinlock_unlock(&TASK->lock); |
153 | spinlock_unlock(&TASK->lock); |
89 | interrupts_restore(ipl); |
154 | interrupts_restore(ipl); |
90 | 155 | ||
91 | klog_printf("udebug_stoppable_end: waitq_sleep"); |
156 | klog_printf("udebug_stoppable_end: waitq_sleep"); |
92 | waitq_sleep(&THREAD->go_wq); |
157 | waitq_sleep(&THREAD->go_wq); |
93 | goto restart; |
158 | goto restart; |
94 | /* must try again - have to lose stoppability atomically */ |
159 | /* must try again - have to lose stoppability atomically */ |
95 | } else { |
160 | } else { |
96 | ++TASK->not_stoppable_count; |
161 | ++TASK->not_stoppable_count; |
- | 162 | THREAD->debug_stoppable = false; |
|
- | 163 | ||
- | 164 | spinlock_unlock(&THREAD->debug_lock); |
|
97 | spinlock_unlock(&TASK->lock); |
165 | spinlock_unlock(&TASK->lock); |
98 | interrupts_restore(ipl); |
166 | interrupts_restore(ipl); |
99 | } |
167 | } |
100 | } |
168 | } |
101 | 169 |