Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/sysinfo/stats.c

    rfe7bcf1 r2fc3b2d  
    6969#define LOAD_INTERVAL  5
    7070
    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 
    7971/** Fixed-point representation of
    8072 *
     
    379371
    380372        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 
    488                 task_t *prev_task = task;
    489                 task = task_next(prev_task);
    490                 task_release(prev_task);
    491         }
    492 
    493         irq_spinlock_unlock(&tasks_lock, true);
    494 
    495         return ((void *) state.data);
    496373}
    497374
     
    877754        sysinfo_set_item_gen_data("system.tasks", NULL, get_stats_tasks, NULL);
    878755        sysinfo_set_item_gen_data("system.threads", NULL, get_stats_threads, NULL);
    879         sysinfo_set_item_gen_data("system.ipccs", NULL, get_stats_ipccs, NULL);
    880756        sysinfo_set_item_gen_data("system.exceptions", NULL, get_stats_exceptions, NULL);
    881757        sysinfo_set_subtree_fn("system.tasks", NULL, get_stats_task, NULL);
Note: See TracChangeset for help on using the changeset viewer.