Rev 3026 | Rev 3031 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3026 | Rev 3030 | ||
---|---|---|---|
Line 97... | Line 97... | ||
97 | rc = waitq_sleep_timeout_unsafe(wq, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE); |
97 | rc = waitq_sleep_timeout_unsafe(wq, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE); |
98 | 98 | ||
99 | waitq_sleep_finish(wq, rc, ipl); |
99 | waitq_sleep_finish(wq, rc, ipl); |
100 | } |
100 | } |
101 | 101 | ||
- | 102 | /** Do a preliminary check that a debugging session is in progress. |
|
- | 103 | * |
|
- | 104 | * This only requires the THREAD->udebug.lock mutex (and not |
|
- | 105 | * TASK->udebug.lock mutex). For an undebugged task, this will |
|
- | 106 | * never block (while there could be collisions by different threads |
|
- | 107 | * on the TASK mutex), thus improving SMP perormance for undebugged tasks. |
|
- | 108 | */ |
|
- | 109 | static bool udebug_thread_precheck(void) |
|
- | 110 | { |
|
- | 111 | bool res; |
|
- | 112 | ||
- | 113 | mutex_lock(&THREAD->udebug.lock); |
|
- | 114 | res = THREAD->udebug.debug_active; |
|
- | 115 | mutex_unlock(&THREAD->udebug.lock); |
|
- | 116 | ||
- | 117 | return res; |
|
- | 118 | } |
|
- | 119 | ||
102 | void udebug_stoppable_begin(void) |
120 | void udebug_stoppable_begin(void) |
103 | { |
121 | { |
104 | int nsc; |
122 | int nsc; |
105 | call_t *db_call, *go_call; |
123 | call_t *db_call, *go_call; |
106 | 124 | ||
107 | ASSERT(THREAD); |
125 | ASSERT(THREAD); |
108 | ASSERT(TASK); |
126 | ASSERT(TASK); |
109 | 127 | ||
110 | udebug_int_lock(); |
128 | udebug_int_lock(); |
111 | 129 | ||
- | 130 | /* Early check for undebugged tasks */ |
|
- | 131 | if (!udebug_thread_precheck()) { |
|
- | 132 | udebug_int_unlock(); |
|
- | 133 | return; |
|
- | 134 | } |
|
- | 135 | ||
112 | mutex_lock(&TASK->udebug.lock); |
136 | mutex_lock(&TASK->udebug.lock); |
113 | 137 | ||
114 | nsc = --TASK->udebug.not_stoppable_count; |
138 | nsc = --TASK->udebug.not_stoppable_count; |
115 | 139 | ||
116 | if (TASK->udebug.dt_state == UDEBUG_TS_BEGINNING) { |
140 | if (TASK->udebug.dt_state == UDEBUG_TS_BEGINNING) { |
Line 192... | Line 216... | ||
192 | } |
216 | } |
193 | } |
217 | } |
194 | 218 | ||
195 | void udebug_stoppable_end(void) |
219 | void udebug_stoppable_end(void) |
196 | { |
220 | { |
- | 221 | /* Early check for undebugged tasks */ |
|
- | 222 | if (!udebug_thread_precheck()) { |
|
- | 223 | udebug_int_unlock(); |
|
- | 224 | return; |
|
- | 225 | } |
|
- | 226 | ||
197 | restart: |
227 | restart: |
198 | mutex_lock(&TASK->udebug.lock); |
228 | mutex_lock(&TASK->udebug.lock); |
199 | 229 | ||
200 | /* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */ |
230 | /* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */ |
201 | mutex_lock(&THREAD->udebug.lock); |
231 | mutex_lock(&THREAD->udebug.lock); |
Line 271... | Line 301... | ||
271 | 301 | ||
272 | etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B; |
302 | etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B; |
273 | 303 | ||
274 | udebug_int_lock(); |
304 | udebug_int_lock(); |
275 | 305 | ||
- | 306 | /* Early check for undebugged tasks */ |
|
- | 307 | if (!udebug_thread_precheck()) { |
|
- | 308 | udebug_int_unlock(); |
|
- | 309 | return; |
|
- | 310 | } |
|
- | 311 | ||
276 | mutex_lock(&TASK->udebug.lock); |
312 | mutex_lock(&TASK->udebug.lock); |
277 | mutex_lock(&THREAD->udebug.lock); |
313 | mutex_lock(&THREAD->udebug.lock); |
278 | 314 | ||
279 | /* Must only generate events when in debugging session and have go */ |
315 | /* Must only generate events when in debugging session and have go */ |
280 | if (THREAD->udebug.debug_active != true || |
316 | if (THREAD->udebug.debug_active != true || |
Line 424... | Line 460... | ||
424 | mutex_lock(&TASK->udebug.lock); |
460 | mutex_lock(&TASK->udebug.lock); |
425 | mutex_lock(&THREAD->udebug.lock); |
461 | mutex_lock(&THREAD->udebug.lock); |
426 | 462 | ||
427 | /* Must only generate events when in debugging session and have go */ |
463 | /* Must only generate events when in debugging session and have go */ |
428 | if (THREAD->udebug.debug_active != true || |
464 | if (THREAD->udebug.debug_active != true || |
429 | THREAD->udebug.stop == true || |
465 | THREAD->udebug.stop == true) { |
- | 466 | mutex_unlock(&THREAD->udebug.lock); |
|
- | 467 | mutex_unlock(&TASK->udebug.lock); |
|
- | 468 | udebug_int_unlock(); |
|
- | 469 | return; |
|
- | 470 | } |
|
- | 471 | ||
- | 472 | /* Verify that the event is enabled */ |
|
430 | (TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) { |
473 | if ((TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) { |
431 | mutex_unlock(&THREAD->udebug.lock); |
474 | mutex_unlock(&THREAD->udebug.lock); |
432 | mutex_unlock(&TASK->udebug.lock); |
475 | mutex_unlock(&TASK->udebug.lock); |
- | 476 | udebug_int_unlock(); |
|
433 | return; |
477 | return; |
434 | } |
478 | } |
435 | 479 | ||
436 | klog_printf("udebug_breakpoint/trap_event"); |
480 | klog_printf("udebug_breakpoint/trap_event"); |
437 | call = THREAD->udebug.go_call; |
481 | call = THREAD->udebug.go_call; |