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 |