Changeset a6302ae in mainline for kernel/generic/src/sysinfo/stats.c
- Timestamp:
- 2019-12-11T10:49:48Z (4 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fe7bcf1
- Parents:
- ad211c8
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/sysinfo/stats.c
rad211c8 ra6302ae 69 69 #define LOAD_INTERVAL 5 70 70 71 /** IPC connections statistics state */ 72 typedef struct { 73 bool counting; 74 size_t count; 75 size_t i; 76 stats_ipcc_t *data; 77 } ipccs_state_t; 78 71 79 /** Fixed-point representation of 72 80 * … … 371 379 372 380 return ((void *) stats_threads); 381 } 382 383 /** Produce IPC connection statistics 384 * 385 * Summarize IPC connection information into IPC connection statistics. 386 * 387 * @param cap Phone capability. 388 * @param arg State variable. 389 * 390 */ 391 static bool produce_stats_ipcc_cb(cap_t *cap, void *arg) 392 { 393 phone_t *phone = cap->kobject->phone; 394 ipccs_state_t *state = (ipccs_state_t *) arg; 395 396 if (state->counting) { 397 /* 398 * Simply update the number of entries 399 * in case we are in the counting mode. 400 */ 401 402 state->count++; 403 return true; 404 } 405 406 /* We are in the gathering mode */ 407 408 if ((state->data == NULL) || (state->i >= state->count)) { 409 /* 410 * Do nothing if we have no buffer 411 * to store the data to (meaning we are 412 * in a dry run) or the buffer is already 413 * full. 414 */ 415 416 return true; 417 } 418 419 mutex_lock(&phone->lock); 420 421 if (phone->state == IPC_PHONE_CONNECTED) { 422 state->data[state->i].caller = phone->caller->taskid; 423 state->data[state->i].callee = phone->callee->task->taskid; 424 state->i++; 425 } 426 427 mutex_unlock(&phone->lock); 428 429 return true; 430 } 431 432 /** Get IPC connections statistics 433 * 434 * @param item Sysinfo item (unused). 435 * @param size Size of the returned data. 436 * @param dry_run Do not get the data, just calculate the size. 437 * @param data Unused. 438 * 439 * @return Data containing several stats_ipccs_t structures. 440 * If the return value is not NULL, it should be freed 441 * in the context of the sysinfo request. 442 * 443 */ 444 static void *get_stats_ipccs(struct sysinfo_item *item, size_t *size, 445 bool dry_run, void *data) 446 { 447 /* Messing with tasks structures, avoid deadlock */ 448 irq_spinlock_lock(&tasks_lock, true); 449 450 ipccs_state_t state = { 451 .counting = true, 452 .count = 0, 453 .i = 0, 454 .data = NULL 455 }; 456 457 /* Compute the number of IPC connections */ 458 task_t *task = task_first(); 459 while (task != NULL) { 460 task_hold(task); 461 irq_spinlock_unlock(&tasks_lock, true); 462 463 caps_apply_to_kobject_type(task, KOBJECT_TYPE_PHONE, 464 produce_stats_ipcc_cb, &state); 465 466 irq_spinlock_lock(&tasks_lock, true); 467 468 task = task_next(task); 469 } 470 471 state.counting = false; 472 *size = sizeof(stats_ipcc_t) * state.count; 473 474 if (!dry_run) 475 state.data = (stats_ipcc_t *) malloc(*size); 476 477 /* Gather the statistics for each task */ 478 task = task_first(); 479 while (task != NULL) { 480 /* We already hold a reference to the task */ 481 irq_spinlock_unlock(&tasks_lock, true); 482 483 caps_apply_to_kobject_type(task, KOBJECT_TYPE_PHONE, 484 produce_stats_ipcc_cb, &state); 485 486 irq_spinlock_lock(&tasks_lock, true); 487 task_release(task); 488 489 task = task_next(task); 490 } 491 492 irq_spinlock_unlock(&tasks_lock, true); 493 494 return ((void *) state.data); 373 495 } 374 496 … … 754 876 sysinfo_set_item_gen_data("system.tasks", NULL, get_stats_tasks, NULL); 755 877 sysinfo_set_item_gen_data("system.threads", NULL, get_stats_threads, NULL); 878 sysinfo_set_item_gen_data("system.ipccs", NULL, get_stats_ipccs, NULL); 756 879 sysinfo_set_item_gen_data("system.exceptions", NULL, get_stats_exceptions, NULL); 757 880 sysinfo_set_subtree_fn("system.tasks", NULL, get_stats_task, NULL);
Note:
See TracChangeset
for help on using the changeset viewer.