Changeset fea0ce6 in mainline for kernel/generic/src/udebug
- Timestamp:
- 2010-01-23T20:20:54Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e095644
- Parents:
- 9d3133d (diff), bc310a05 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- kernel/generic/src/udebug
- Files:
-
- 3 edited
-
udebug.c (modified) (2 diffs)
-
udebug_ipc.c (modified) (5 diffs)
-
udebug_ops.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/udebug/udebug.c
r9d3133d rfea0ce6 69 69 mutex_initialize(&ut->lock, MUTEX_PASSIVE); 70 70 waitq_initialize(&ut->go_wq); 71 condvar_initialize(&ut->active_cv); 71 72 72 73 ut->go_call = NULL; … … 446 447 waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST); 447 448 } 449 mutex_unlock(&t->udebug.lock); 450 condvar_broadcast(&t->udebug.active_cv); 451 } else { 452 mutex_unlock(&t->udebug.lock); 448 453 } 449 mutex_unlock(&t->udebug.lock);450 454 } 451 455 -
kernel/generic/src/udebug/udebug_ipc.c
r9d3133d rfea0ce6 41 41 #include <proc/task.h> 42 42 #include <proc/thread.h> 43 #include <mm/as.h> 43 44 #include <arch.h> 44 45 #include <errno.h> … … 165 166 static void udebug_receive_thread_read(call_t *call) 166 167 { 168 uintptr_t uspace_addr; 169 size_t buf_size; 170 void *buffer; 171 size_t copied, needed; 172 int rc; 173 174 uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */ 175 buf_size = IPC_GET_ARG3(call->data); /* Dest. buffer size */ 176 177 /* 178 * Read thread list. Variable n will be filled with actual number 179 * of threads times thread-id size. 180 */ 181 rc = udebug_thread_read(&buffer, buf_size, &copied, &needed); 182 if (rc < 0) { 183 IPC_SET_RETVAL(call->data, rc); 184 ipc_answer(&TASK->kb.box, call); 185 return; 186 } 187 188 /* 189 * Make use of call->buffer to transfer data to caller's userspace 190 */ 191 192 IPC_SET_RETVAL(call->data, 0); 193 /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that 194 same code in process_answer() can be used 195 (no way to distinguish method in answer) */ 196 IPC_SET_ARG1(call->data, uspace_addr); 197 IPC_SET_ARG2(call->data, copied); 198 IPC_SET_ARG3(call->data, needed); 199 call->buffer = buffer; 200 201 ipc_answer(&TASK->kb.box, call); 202 } 203 204 /** Process an AREAS_READ call. 205 * 206 * Returns a list of address space areas in the current task, as an array 207 * of as_area_info_t structures. 208 * 209 * @param call The call structure. 210 */ 211 static void udebug_receive_areas_read(call_t *call) 212 { 167 213 unative_t uspace_addr; 168 214 unative_t to_copy; 169 unsigned total_bytes; 170 unsigned buf_size; 171 void *buffer; 172 size_t n; 173 int rc; 215 size_t data_size; 216 size_t buf_size; 217 void *data; 174 218 175 219 uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */ … … 177 221 178 222 /* 179 * Read thread list. Variable n will be filled with actual number 180 * of threads times thread-id size. 181 */ 182 rc = udebug_thread_read(&buffer, buf_size, &n); 183 if (rc < 0) { 184 IPC_SET_RETVAL(call->data, rc); 185 ipc_answer(&TASK->kb.box, call); 186 return; 187 } 188 189 total_bytes = n; 190 191 /* Copy MAX(buf_size, total_bytes) bytes */ 192 193 if (buf_size > total_bytes) 194 to_copy = total_bytes; 223 * Read area list. 224 */ 225 as_get_area_info(AS, (as_area_info_t **) &data, &data_size); 226 227 /* Copy MAX(buf_size, data_size) bytes */ 228 229 if (buf_size > data_size) 230 to_copy = data_size; 195 231 else 196 232 to_copy = buf_size; … … 207 243 IPC_SET_ARG2(call->data, to_copy); 208 244 209 IPC_SET_ARG3(call->data, total_bytes); 210 call->buffer = buffer; 211 212 ipc_answer(&TASK->kb.box, call); 213 } 245 IPC_SET_ARG3(call->data, data_size); 246 call->buffer = data; 247 248 ipc_answer(&TASK->kb.box, call); 249 } 250 214 251 215 252 /** Process an ARGS_READ call. … … 331 368 udebug_receive_thread_read(call); 332 369 break; 370 case UDEBUG_M_AREAS_READ: 371 udebug_receive_areas_read(call); 372 break; 333 373 case UDEBUG_M_ARGS_READ: 334 374 udebug_receive_args_read(call); -
kernel/generic/src/udebug/udebug_ops.c
r9d3133d rfea0ce6 209 209 210 210 mutex_lock(&t->udebug.lock); 211 if ((t->flags & THREAD_FLAG_USPACE) != 0) 211 if ((t->flags & THREAD_FLAG_USPACE) != 0) { 212 212 t->udebug.active = true; 213 mutex_unlock(&t->udebug.lock); 213 mutex_unlock(&t->udebug.lock); 214 condvar_broadcast(&t->udebug.active_cv); 215 } else { 216 mutex_unlock(&t->udebug.lock); 217 } 214 218 } 215 219 … … 355 359 * 356 360 * If the sequence is longer than @a buf_size bytes, only as much hashes 357 * as can fit are copied. The number of thread hashes copied is stored 358 * in @a n. 361 * as can fit are copied. The number of bytes copied is stored in @a stored. 362 * The total number of thread bytes that could have been saved had there been 363 * enough space is stored in @a needed. 359 364 * 360 365 * The rationale for having @a buf_size is that this function is only … … 364 369 * @param buffer The buffer for storing thread hashes. 365 370 * @param buf_size Buffer size in bytes. 366 * @param n The actual number of hashes copied will be stored here. 367 */ 368 int udebug_thread_read(void **buffer, size_t buf_size, size_t *n) 371 * @param stored The actual number of bytes copied will be stored here. 372 * @param needed Total number of hashes that could have been saved. 373 */ 374 int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored, 375 size_t *needed) 369 376 { 370 377 thread_t *t; 371 378 link_t *cur; 372 379 unative_t tid; 373 unsigned copied_ids; 380 size_t copied_ids; 381 size_t extra_ids; 374 382 ipl_t ipl; 375 383 unative_t *id_buffer; … … 380 388 381 389 /* Allocate a buffer to hold thread IDs */ 382 id_buffer = malloc(buf_size , 0);390 id_buffer = malloc(buf_size + 1, 0); 383 391 384 392 mutex_lock(&TASK->udebug.lock); … … 396 404 max_ids = buf_size / sizeof(unative_t); 397 405 copied_ids = 0; 406 extra_ids = 0; 398 407 399 408 /* FIXME: make sure the thread isn't past debug shutdown... */ 400 409 for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { 401 /* Do not write past end of buffer */402 if (copied_ids >= max_ids) break;403 404 410 t = list_get_instance(cur, thread_t, th_link); 405 411 … … 409 415 410 416 /* Not interested in kernel threads. */ 411 if ((flags & THREAD_FLAG_USPACE) != 0) { 417 if ((flags & THREAD_FLAG_USPACE) == 0) 418 continue; 419 420 if (copied_ids < max_ids) { 412 421 /* Using thread struct pointer as identification hash */ 413 422 tid = (unative_t) t; 414 423 id_buffer[copied_ids++] = tid; 424 } else { 425 extra_ids++; 415 426 } 416 427 } … … 422 433 423 434 *buffer = id_buffer; 424 *n = copied_ids * sizeof(unative_t); 435 *stored = copied_ids * sizeof(unative_t); 436 *needed = (copied_ids + extra_ids) * sizeof(unative_t); 425 437 426 438 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.
