Rev 2896 | Rev 2898 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2896 | Rev 2897 | ||
|---|---|---|---|
| Line 233... | Line 233... | ||
| 233 | 233 | ||
| 234 | return 0; |
234 | return 0; |
| 235 | } |
235 | } |
| 236 | 236 | ||
| 237 | 237 | ||
| 238 | int udebug_thread_read(void **buffer, size_t *n) |
238 | int udebug_thread_read(void **buffer, size_t buf_size, size_t *n) |
| 239 | { |
239 | { |
| 240 | thread_t *t; |
240 | thread_t *t; |
| 241 | link_t *cur; |
241 | link_t *cur; |
| 242 | unative_t tid; |
242 | unative_t tid; |
| 243 | unsigned num_threads, copied_ids; |
243 | unsigned copied_ids; |
| 244 | ipl_t ipl; |
244 | ipl_t ipl; |
| 245 | unative_t *id_buffer; |
245 | unative_t *id_buffer; |
| 246 | int flags; |
246 | int flags; |
| - | 247 | size_t max_ids; |
|
| 247 | 248 | ||
| 248 | klog_printf("udebug_thread_read()"); |
249 | klog_printf("udebug_thread_read()"); |
| 249 | 250 | ||
| - | 251 | /* Allocate a buffer to hold thread IDs */ |
|
| - | 252 | id_buffer = malloc(buf_size, 0); |
|
| - | 253 | if (!id_buffer) return ENOMEM; |
|
| - | 254 | ||
| 250 | ipl = interrupts_disable(); |
255 | ipl = interrupts_disable(); |
| 251 | spinlock_lock(&TASK->lock); |
256 | spinlock_lock(&TASK->lock); |
| 252 | 257 | ||
| 253 | /* Verify task state */ |
258 | /* Verify task state */ |
| 254 | if (TASK->dt_state != UDEBUG_TS_ACTIVE) { |
259 | if (TASK->dt_state != UDEBUG_TS_ACTIVE) { |
| Line 256... | Line 261... | ||
| 256 | interrupts_restore(ipl); |
261 | interrupts_restore(ipl); |
| 257 | 262 | ||
| 258 | return EINVAL; |
263 | return EINVAL; |
| 259 | } |
264 | } |
| 260 | 265 | ||
| 261 | /* Count the threads first */ |
266 | /* Copy down the thread IDs */ |
| 262 | - | ||
| 263 | num_threads = 0; |
- | |
| 264 | for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { |
- | |
| 265 | /* Count all threads, to be on the safe side */ |
- | |
| 266 | ++num_threads; |
- | |
| 267 | } |
- | |
| 268 | - | ||
| 269 | /* Allocate a buffer and copy down the threads' ids */ |
- | |
| 270 | //FIXME!!! must not malloc when locks are held |
- | |
| 271 | id_buffer = malloc(num_threads * sizeof(unative_t), 0); |
- | |
| 272 | if (!id_buffer) { |
- | |
| 273 | spinlock_unlock(&TASK->lock); |
- | |
| 274 | interrupts_restore(ipl); |
- | |
| 275 | - | ||
| 276 | return ENOMEM; |
- | |
| 277 | } |
- | |
| 278 | 267 | ||
| - | 268 | max_ids = buf_size / sizeof(unative_t); |
|
| 279 | copied_ids = 0; |
269 | copied_ids = 0; |
| - | 270 | ||
| 280 | for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { |
271 | for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { |
| - | 272 | /* Do not write past end of buffer */ |
|
| - | 273 | if (copied_ids >= max_ids) break; |
|
| - | 274 | ||
| 281 | t = list_get_instance(cur, thread_t, th_link); |
275 | t = list_get_instance(cur, thread_t, th_link); |
| 282 | 276 | ||
| 283 | spinlock_lock(&t->lock); |
277 | spinlock_lock(&t->lock); |
| 284 | flags = t->flags; |
278 | flags = t->flags; |
| 285 | spinlock_unlock(&t->lock); |
279 | spinlock_unlock(&t->lock); |
| 286 | 280 | ||
| 287 | /* Not interested in kernel threads */ |
281 | /* Not interested in kernel threads */ |
| 288 | if ((flags & THREAD_FLAG_USPACE) != 0) { |
282 | if ((flags & THREAD_FLAG_USPACE) != 0) { |
| 289 | /* Using thread struct pointer for identification */ |
283 | /* Using thread struct pointer as identification hash */ |
| 290 | tid = (unative_t) t; |
284 | tid = (unative_t) t; |
| 291 | id_buffer[copied_ids++] = tid; |
285 | id_buffer[copied_ids++] = tid; |
| 292 | } |
286 | } |
| 293 | } |
287 | } |
| 294 | 288 | ||