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