Changeset 80bfb601 in mainline


Ignore:
Timestamp:
2010-04-18T09:57:19Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d869398
Parents:
fce3536
Message:

improve sysinfo and stats documentation (no change in functionality)

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/sysinfo/abi.h

    rfce3536 r80bfb601  
    3131 */
    3232/** @file
     33 * Data structures passed between kernel sysinfo and user space.
    3334 */
    3435
     
    3637#define KERN_ABI_H_
    3738
     39/** Number of load components */
    3840#define LOAD_STEPS        3
     41
     42/** Maximum task name size */
    3943#define TASK_NAME_BUFLEN  20
    4044
     45/** Statistics about a single CPU
     46 *
     47 */
    4148typedef struct {
    42         unsigned int id;
    43         uint16_t frequency_mhz;
    44         uint64_t idle_ticks;
    45         uint64_t busy_ticks;
     49        unsigned int id;         /**< CPU ID as stored by kernel */
     50        uint16_t frequency_mhz;  /**< Frequency in MHz */
     51        uint64_t idle_ticks;     /**< Number of idle kernel quanta */
     52        uint64_t busy_ticks;     /**< Number of busy kernel quanta */
    4653} stats_cpu_t;
    4754
     55/** Physical memory statistics
     56 *
     57 */
    4858typedef struct {
    49         uint64_t total;
    50         uint64_t unavail;
    51         uint64_t used;
    52         uint64_t free;
     59        uint64_t total;    /**< Total physical memory (bytes) */
     60        uint64_t unavail;  /**< Unavailable (reserved, firmware) bytes */
     61        uint64_t used;     /**< Allocated physical memory (bytes) */
     62        uint64_t free;     /**< Free physical memory (bytes) */
    5363} stats_physmem_t;
    5464
     65/** IPC statistics
     66 *
     67 * Associated with a task.
     68 *
     69 */
    5570typedef struct {
    56         uint64_t call_sent;
    57         uint64_t call_recieved;
    58         uint64_t answer_sent;
    59         uint64_t answer_recieved;
    60         uint64_t irq_notif_recieved;
    61         uint64_t forwarded;
     71        uint64_t call_sent;           /**< IPC calls sent */
     72        uint64_t call_recieved;       /**< IPC calls received */
     73        uint64_t answer_sent;         /**< IPC answers sent */
     74        uint64_t answer_recieved;     /**< IPC answers received */
     75        uint64_t irq_notif_recieved;  /**< IPC IRQ notifications */
     76        uint64_t forwarded;           /**< IPC messages forwarded */
    6277} stats_ipc_t;
    6378
     79/** Statistics about a single task
     80 *
     81 */
    6482typedef struct {
    65         char name[TASK_NAME_BUFLEN];
    66         size_t virtmem;
    67         size_t threads;
    68         uint64_t ucycles;
    69         uint64_t kcycles;
    70         stats_ipc_t ipc_info;
     83        char name[TASK_NAME_BUFLEN];  /**< Task name (in kernel) */
     84        size_t virtmem;               /**< Size of VAS (bytes) */
     85        size_t threads;               /**< Number of threads */
     86        uint64_t ucycles;             /**< Number of CPU cycles in user space */
     87        uint64_t kcycles;             /**< Number of CPU cycles in kernel */
     88        stats_ipc_t ipc_info;         /**< IPC statistics */
    7189} stats_task_t;
    7290
     91/** Load fixed-point value */
    7392typedef uint32_t load_t;
    7493
  • kernel/generic/include/sysinfo/sysinfo.h

    rfce3536 r80bfb601  
    3939#include <str.h>
    4040
     41/** Framebuffer info exported flags */
    4142extern bool fb_exported;
    4243
     44/** Item value type
     45 *
     46 */
    4347typedef enum {
    44         SYSINFO_VAL_UNDEFINED = 0,
    45         SYSINFO_VAL_VAL = 1,
    46         SYSINFO_VAL_DATA = 2,
    47         SYSINFO_VAL_FUNCTION_VAL = 3,
    48         SYSINFO_VAL_FUNCTION_DATA = 4
     48        SYSINFO_VAL_UNDEFINED = 0,     /**< Undefined value */
     49        SYSINFO_VAL_VAL = 1,           /**< Constant numeric value */
     50        SYSINFO_VAL_DATA = 2,          /**< Constant binary data */
     51        SYSINFO_VAL_FUNCTION_VAL = 3,  /**< Generated numeric value */
     52        SYSINFO_VAL_FUNCTION_DATA = 4  /**< Generated binary data */
    4953} sysinfo_item_val_type_t;
    5054
     55/** Subtree type
     56 *
     57 */
    5158typedef enum {
    52         SYSINFO_SUBTREE_NONE = 0,
    53         SYSINFO_SUBTREE_TABLE = 1,
    54         SYSINFO_SUBTREE_FUNCTION = 2
     59        SYSINFO_SUBTREE_NONE = 0,     /**< No subtree (leaf item) */
     60        SYSINFO_SUBTREE_TABLE = 1,    /**< Fixed subtree */
     61        SYSINFO_SUBTREE_FUNCTION = 2  /**< Generated subtree */
    5562} sysinfo_subtree_type_t;
    5663
    5764struct sysinfo_item;
    5865
     66/** Gerated numeric value function */
    5967typedef unative_t (*sysinfo_fn_val_t)(struct sysinfo_item *);
     68
     69/** Generated binary data function */
    6070typedef void *(*sysinfo_fn_data_t)(struct sysinfo_item *, size_t *);
    6171
     72/** Sysinfo item binary data
     73 *
     74 */
    6275typedef struct {
    63         void *data;
    64         size_t size;
     76        void *data;   /**< Data */
     77        size_t size;  /**< Size (bytes) */
    6578} sysinfo_data_t;
    6679
     80/** Sysinfo item value (union)
     81 *
     82 */
    6783typedef union {
    68         unative_t val;
    69         sysinfo_fn_val_t fn_val;
    70         sysinfo_fn_data_t fn_data;
    71         sysinfo_data_t data;
     84        unative_t val;              /**< Constant numberic value */
     85        sysinfo_fn_val_t fn_val;    /**< Generated numeric value function */
     86        sysinfo_fn_data_t fn_data;  /**< Generated binary data function */
     87        sysinfo_data_t data;        /**< Constant binary data */
    7288} sysinfo_item_val_t;
    7389
     90/** Sysinfo return holder
     91 *
     92 * This structure is generated from the constant
     93 * items or by the generating functions. Note that
     94 * the validity of the data is limited by the scope
     95 * of single sysinfo invocation guarded by sysinfo_lock.
     96 *
     97 */
    7498typedef struct {
    75         sysinfo_item_val_type_t tag;
     99        sysinfo_item_val_type_t tag;  /**< Return value type */
    76100        union {
    77                 unative_t val;
    78                 sysinfo_data_t data;
     101                unative_t val;            /**< Numberic value */
     102                sysinfo_data_t data;      /**< Binary data */
    79103        };
    80104} sysinfo_return_t;
    81105
     106/** Generated subtree function */
    82107typedef sysinfo_return_t (*sysinfo_fn_subtree_t)(const char *);
    83108
     109/** Sysinfo subtree (union)
     110 *
     111 */
    84112typedef union {
    85         struct sysinfo_item *table;
    86         sysinfo_fn_subtree_t get_data;
     113        struct sysinfo_item *table;     /**< Fixed subtree (list of subitems) */
     114        sysinfo_fn_subtree_t get_data;  /**< Generated subtree function */
    87115} sysinfo_subtree_t;
    88116
     117/** Sysinfo item
     118 *
     119 */
    89120typedef struct sysinfo_item {
    90         char *name;
     121        char *name;                           /**< Item name */
    91122       
    92         sysinfo_item_val_type_t val_type;
    93         sysinfo_item_val_t val;
     123        sysinfo_item_val_type_t val_type;     /**< Item value type */
     124        sysinfo_item_val_t val;               /**< Item value */
    94125       
    95         sysinfo_subtree_type_t subtree_type;
    96         sysinfo_subtree_t subtree;
     126        sysinfo_subtree_type_t subtree_type;  /**< Subtree type */
     127        sysinfo_subtree_t subtree;            /**< Subtree */
    97128       
    98         struct sysinfo_item *next;
     129        struct sysinfo_item *next;            /**< Sibling item */
    99130} sysinfo_item_t;
    100131
     
    114145extern void sysinfo_dump(sysinfo_item_t *);
    115146
    116 unative_t sys_sysinfo_get_tag(void *, size_t);
    117 unative_t sys_sysinfo_get_value(void *, size_t, void *);
    118 unative_t sys_sysinfo_get_data_size(void *, size_t, void *);
    119 unative_t sys_sysinfo_get_data(void *, size_t, void *, size_t);
     147extern unative_t sys_sysinfo_get_tag(void *, size_t);
     148extern unative_t sys_sysinfo_get_value(void *, size_t, void *);
     149extern unative_t sys_sysinfo_get_data_size(void *, size_t, void *);
     150extern unative_t sys_sysinfo_get_data(void *, size_t, void *, size_t);
    120151
    121152#endif
  • kernel/generic/src/sysinfo/stats.c

    rfce3536 r80bfb601  
    5555#define LOAD_INTERVAL  5
    5656
    57 /**
    58  * Fixed-point representation of:
     57/** Fixed-point representation of
    5958 *
    6059 * 1 / exp(5 sec / 1 min)
     
    6463 */
    6564static load_t load_exp[LOAD_STEPS] = {1884, 2014, 2037};
     65
     66/** Running average of the number of ready threads */
    6667static load_t avenrdy[LOAD_STEPS] = {0, 0, 0};
     68
     69/** Load calculation spinlock */
    6770SPINLOCK_STATIC_INITIALIZE_NAME(load_lock, "load_lock");
    6871
     72/** Get system uptime
     73 *
     74 * @param item Sysinfo item (unused).
     75 *
     76 * @return System uptime (in secords).
     77 *
     78 */
    6979static unative_t get_stats_uptime(struct sysinfo_item *item)
    7080{
     
    7383}
    7484
     85/** Get statistics of all CPUs
     86 *
     87 * @param item Sysinfo item (unused).
     88 * @param size Size of the returned data.
     89 *
     90 * @return Data containing several stats_cpu_t structures.
     91 *         If the return value is not NULL, it should be freed
     92 *         in the context of the sysinfo request.
     93 */
    7594static void *get_stats_cpus(struct sysinfo_item *item, size_t *size)
    7695{
     96        /* Assumption: config.cpu_count is constant */
    7797        stats_cpu_t *stats_cpus =
    7898            (stats_cpu_t *) malloc(sizeof(stats_cpu_t) * config.cpu_count,
     
    83103        }
    84104       
     105        /* Each CPU structure is locked separatelly */
    85106        ipl_t ipl = interrupts_disable();
    86107       
     
    103124}
    104125
     126/** Count number of tasks
     127 *
     128 * AVL task tree walker for counting tasks.
     129 *
     130 * @param node AVL task tree node (unused).
     131 * @param arg  Pointer to the counter.
     132 *
     133 * @param Always true (continue the walk).
     134 *
     135 */
    105136static bool task_count_walker(avltree_node_t *node, void *arg)
    106137{
     
    111142}
    112143
     144/** Gather tasks
     145 *
     146 * AVL task tree walker for gathering task IDs. Interrupts should
     147 * be already disabled while walking the tree.
     148 *
     149 * @param node AVL task tree node.
     150 * @param arg  Pointer to the iterator into the array of task IDs.
     151 *
     152 * @param Always true (continue the walk).
     153 *
     154 */
    113155static bool task_serialize_walker(avltree_node_t *node, void *arg)
    114156{
     
    116158        task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);
    117159       
     160        /* Interrupts are already disabled */
    118161        spinlock_lock(&(task->lock));
    119162       
     163        /* Record the ID and increment the iterator */
    120164        **ids = task->taskid;
    121165        (*ids)++;
     
    126170}
    127171
     172/** Get task IDs
     173 *
     174 * @param item Sysinfo item (unused).
     175 * @param size Size of the returned data.
     176 *
     177 * @return Data containing task IDs of all tasks.
     178 *         If the return value is not NULL, it should be freed
     179 *         in the context of the sysinfo request.
     180 */
    128181static void *get_stats_tasks(struct sysinfo_item *item, size_t *size)
    129182{
     
    132185        spinlock_lock(&tasks_lock);
    133186       
     187        /* First walk the task tree to count the tasks */
    134188        size_t count = 0;
    135189        avltree_walk(&tasks_tree, task_count_walker, (void *) &count);
    136190       
    137191        if (count == 0) {
     192                /* No tasks found (strange) */
    138193                spinlock_unlock(&tasks_lock);
    139194                interrupts_restore(ipl);
     
    146201            (task_id_t *) malloc(sizeof(task_id_t) * count, FRAME_ATOMIC);
    147202        if (task_ids == NULL) {
     203                /* No free space for allocation */
    148204                spinlock_unlock(&tasks_lock);
    149205                interrupts_restore(ipl);
     
    153209        }
    154210       
     211        /* Walk tha task tree again to gather the IDs */
    155212        task_id_t *iterator = task_ids;
    156213        avltree_walk(&tasks_tree, task_serialize_walker, (void *) &iterator);
     
    163220}
    164221
     222/** Get the size of a virtual address space
     223 *
     224 * @param as Address space.
     225 *
     226 * @return Size of the mapped virtual address space (bytes).
     227 *
     228 */
    165229static size_t get_task_virtmem(as_t *as)
    166230{
     
    169233        size_t result = 0;
    170234       
     235        /* Walk the B+ tree and count pages */
    171236        link_t *cur;
    172237        for (cur = as->as_area_btree.leaf_head.next;
     
    190255}
    191256
     257/** Get task statistics
     258 *
     259 * Get statistics of a given task. The task ID is passed
     260 * as a string (current limitation of the sysinfo interface,
     261 * but it is still reasonable for the given purpose).
     262 *
     263 * @param name Task ID (string-encoded number).
     264 *
     265 * @return Sysinfo return holder. The type of the returned
     266 *         data is either SYSINFO_VAL_UNDEFINED (unknown
     267 *         task ID or memory allocation error) or
     268 *         SYSINFO_VAL_FUNCTION_DATA (in that case the
     269 *         generated data should be freed within the
     270 *         sysinfo request context).
     271 *
     272 */
    192273static sysinfo_return_t get_stats_task(const char *name)
    193274{
    194        
     275        /* Initially no return value */
    195276        sysinfo_return_t ret;
    196277        ret.tag = SYSINFO_VAL_UNDEFINED;
    197278       
     279        /* Parse the task ID */
    198280        task_id_t task_id;
    199281        if (str_uint64(name, NULL, 0, true, &task_id) != EOK)
    200282                return ret;
    201283       
     284        /* Allocate stats_task_t structure */
    202285        stats_task_t *stats_task =
    203286            (stats_task_t *) malloc(sizeof(stats_task_t), FRAME_ATOMIC);
     
    205288                return ret;
    206289       
     290        /* Messing with task structures, avoid deadlock */
    207291        ipl_t ipl = interrupts_disable();
    208292        spinlock_lock(&tasks_lock);
     
    210294        task_t *task = task_find_by_id(task_id);
    211295        if (task == NULL) {
     296                /* No task with this ID */
    212297                spinlock_unlock(&tasks_lock);
    213298                interrupts_restore(ipl);
     
    216301        }
    217302       
     303        /* Hand-over-hand locking */
    218304        spinlock_lock(&task->lock);
    219305        spinlock_unlock(&tasks_lock);
    220306       
     307        /* Copy task's statistics */
    221308        str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name);
    222309        stats_task->virtmem = get_task_virtmem(task->as);
     
    229316        interrupts_restore(ipl);
    230317       
     318        /* Correct return value */
    231319        ret.tag = SYSINFO_VAL_FUNCTION_DATA;
    232320        ret.data.data = (void *) stats_task;
     
    236324}
    237325
     326/** Get physical memory statistics
     327 *
     328 * @param item Sysinfo item (unused).
     329 * @param size Size of the returned data.
     330 *
     331 * @return Data containing stats_physmem_t.
     332 *         If the return value is not NULL, it should be freed
     333 *         in the context of the sysinfo request.
     334 */
    238335static void *get_stats_physmem(struct sysinfo_item *item, size_t *size)
    239336{
     
    252349}
    253350
     351/** Get system load
     352 *
     353 * @param item Sysinfo item (unused).
     354 * @param size Size of the returned data.
     355 *
     356 * @return Data several load_t values.
     357 *         If the return value is not NULL, it should be freed
     358 *         in the context of the sysinfo request.
     359 */
    254360static void *get_stats_load(struct sysinfo_item *item, size_t *size)
    255361{
     
    261367        }
    262368       
     369        /* To always get consistent values acquire the spinlock */
    263370        ipl_t ipl = interrupts_disable();
    264371        spinlock_lock(&load_lock);
     
    324431       
    325432        while (true) {
     433                /* Mutually exclude with get_stats_load() */
    326434                ipl_t ipl = interrupts_disable();
    327435                spinlock_lock(&load_lock);
     
    340448}
    341449
     450/** Register sysinfo statistical items
     451 *
     452 */
    342453void stats_init(void)
    343454{
  • kernel/generic/src/sysinfo/sysinfo.c

    rfce3536 r80bfb601  
    4141#include <errno.h>
    4242
     43/** Maximal sysinfo path length */
    4344#define SYSINFO_MAX_PATH  2048
    4445
    4546bool fb_exported = false;
    4647
     48/** Global sysinfo tree root item */
    4749static sysinfo_item_t *global_root = NULL;
     50
     51/** Sysinfo SLAB cache */
    4852static slab_cache_t *sysinfo_item_slab;
    4953
     54/** Sysinfo spinlock */
    5055SPINLOCK_STATIC_INITIALIZE_NAME(sysinfo_lock, "sysinfo_lock");
    5156
     57/** Sysinfo item constructor
     58 *
     59 */
    5260static int sysinfo_item_constructor(void *obj, int kmflag)
    5361{
     
    6371}
    6472
     73/** Sysinfo item destructor
     74 *
     75 * Note that the return value is not perfectly correct
     76 * since more space might get actually freed thanks
     77 * to the disposal of item->name
     78 *
     79 */
    6580static int sysinfo_item_destructor(void *obj)
    6681{
     
    7388}
    7489
     90/** Initialize sysinfo subsystem
     91 *
     92 * Create SLAB cache for sysinfo items.
     93 *
     94 */
    7595void sysinfo_init(void)
    7696{
     
    80100}
    81101
    82 /** Recursively find item in sysinfo tree
     102/** Recursively find an item in sysinfo tree
    83103 *
    84104 * Should be called with interrupts disabled
    85105 * and sysinfo_lock held.
    86106 *
     107 * @param name    Current sysinfo path suffix.
     108 * @param subtree Current sysinfo (sub)tree root item.
     109 * @param ret     If the return value is NULL, this argument
     110 *                can be either also NULL (i.e. no item was
     111 *                found and no data was generated) or the
     112 *                original pointer is used to store the value
     113 *                generated by a generated subtree function.
     114 *
     115 * @return Found item or NULL if no item in the fixed tree
     116 *         was found (N.B. ret).
     117 *
    87118 */
    88119static sysinfo_item_t *sysinfo_find_item(const char *name,
     
    94125        sysinfo_item_t *cur = subtree;
    95126       
     127        /* Walk all siblings */
    96128        while (cur != NULL) {
    97129                size_t i = 0;
     
    118150                                return NULL;
    119151                        default:
    120                                 /* Not found */
     152                                /* Not found, no data generated */
    121153                                *ret = NULL;
    122154                                return NULL;
     
    127159        }
    128160       
     161        /* Not found, no data generated */
    129162        *ret = NULL;
    130163        return NULL;
     
    135168 * Should be called with interrupts disabled
    136169 * and sysinfo_lock held.
     170 *
     171 * @param name     Current sysinfo path suffix.
     172 * @param psubtree Pointer to an already existing (sub)tree root
     173 *                 item or where to store a new tree root item.
     174 *
     175 * @return Existing or newly allocated sysinfo item or NULL
     176 *         if the current tree configuration does not allow to
     177 *         create a new item.
    137178 *
    138179 */
     
    172213        sysinfo_item_t *cur = *psubtree;
    173214       
     215        /* Walk all siblings */
    174216        while (cur != NULL) {
    175217                size_t i = 0;
     
    199241                        default:
    200242                                /* Subtree items handled by a function, this
    201                                  * cannot be overriden.
     243                                 * cannot be overriden by a constant item.
    202244                                 */
    203245                                return NULL;
     
    235277                }
    236278               
    237                 /* Get next sibling */
    238279                cur = cur->next;
    239280        }
     
    244285}
    245286
     287/** Set sysinfo item with a constant numeric value
     288 *
     289 * @param name Sysinfo path.
     290 * @param root Pointer to the root item or where to store
     291 *             a new root item (NULL for global sysinfo root).
     292 * @param val  Value to store in the item.
     293 *
     294 */
    246295void sysinfo_set_item_val(const char *name, sysinfo_item_t **root,
    247296    unative_t val)
    248297{
     298        /* Protect sysinfo tree consistency */
    249299        ipl_t ipl = interrupts_disable();
    250300        spinlock_lock(&sysinfo_lock);
     
    263313}
    264314
     315/** Set sysinfo item with a constant binary data
     316 *
     317 * Note that sysinfo only stores the pointer to the
     318 * binary data and does not touch it in any way. The
     319 * data should be static and immortal.
     320 *
     321 * @param name Sysinfo path.
     322 * @param root Pointer to the root item or where to store
     323 *             a new root item (NULL for global sysinfo root).
     324 * @param data Binary data.
     325 * @param size Size of the binary data.
     326 *
     327 */
    265328void sysinfo_set_item_data(const char *name, sysinfo_item_t **root,
    266329    void *data, size_t size)
    267330{
     331        /* Protect sysinfo tree consistency */
    268332        ipl_t ipl = interrupts_disable();
    269333        spinlock_lock(&sysinfo_lock);
     
    283347}
    284348
     349/** Set sysinfo item with a generated numeric value
     350 *
     351 * @param name Sysinfo path.
     352 * @param root Pointer to the root item or where to store
     353 *             a new root item (NULL for global sysinfo root).
     354 * @param fn   Numeric value generator function.
     355 *
     356 */
    285357void sysinfo_set_item_fn_val(const char *name, sysinfo_item_t **root,
    286358    sysinfo_fn_val_t fn)
    287359{
     360        /* Protect sysinfo tree consistency */
    288361        ipl_t ipl = interrupts_disable();
    289362        spinlock_lock(&sysinfo_lock);
     
    302375}
    303376
     377/** Set sysinfo item with a generated binary data
     378 *
     379 * Note that each time the generator function is called
     380 * it is supposed to return a new dynamically allocated
     381 * data. This data is then freed by sysinfo in the context
     382 * of the current sysinfo request.
     383 *
     384 * @param name Sysinfo path.
     385 * @param root Pointer to the root item or where to store
     386 *             a new root item (NULL for global sysinfo root).
     387 * @param fn   Binary data generator function.
     388 *
     389 */
    304390void sysinfo_set_item_fn_data(const char *name, sysinfo_item_t **root,
    305391    sysinfo_fn_data_t fn)
    306392{
     393        /* Protect sysinfo tree consistency */
    307394        ipl_t ipl = interrupts_disable();
    308395        spinlock_lock(&sysinfo_lock);
     
    321408}
    322409
     410/** Set sysinfo item with an undefined value
     411 *
     412 * @param name Sysinfo path.
     413 * @param root Pointer to the root item or where to store
     414 *             a new root item (NULL for global sysinfo root).
     415 *
     416 */
    323417void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root)
    324418{
     419        /* Protect sysinfo tree consistency */
    325420        ipl_t ipl = interrupts_disable();
    326421        spinlock_lock(&sysinfo_lock);
     
    337432}
    338433
     434/** Set sysinfo item with a generated subtree
     435 *
     436 * @param name Sysinfo path.
     437 * @param root Pointer to the root item or where to store
     438 *             a new root item (NULL for global sysinfo root).
     439 * @param fn   Subtree generator function.
     440 *
     441 */
    339442void sysinfo_set_subtree_fn(const char *name, sysinfo_item_t **root,
    340443    sysinfo_fn_subtree_t fn)
    341444{
     445        /* Protect sysinfo tree consistency */
    342446        ipl_t ipl = interrupts_disable();
    343447        spinlock_lock(&sysinfo_lock);
     
    347451       
    348452        sysinfo_item_t *item = sysinfo_create_path(name, root);
     453       
     454        /* Change the type of the subtree only if it is not already
     455           a fixed subtree */
    349456        if ((item != NULL) && (item->subtree_type != SYSINFO_SUBTREE_TABLE)) {
    350457                item->subtree_type = SYSINFO_SUBTREE_FUNCTION;
     
    357464
    358465/** Sysinfo dump indentation helper routine
     466 *
     467 * @param depth Number of indentation characters to print.
    359468 *
    360469 */
     
    374483 * there is no better simple solution.
    375484 *
     485 * @param root  Root item of the current (sub)tree.
     486 * @param depth Current depth in the sysinfo tree.
     487 *
    376488 */
    377489static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth)
     
    379491        sysinfo_item_t *cur = root;
    380492       
     493        /* Walk all siblings */
    381494        while (cur != NULL) {
    382495                sysinfo_indent(depth);
     
    386499                size_t size;
    387500               
     501                /* Display node value and type */
    388502                switch (cur->val_type) {
    389503                case SYSINFO_VAL_UNDEFINED:
     
    405519                case SYSINFO_VAL_FUNCTION_DATA:
    406520                        data = cur->val.fn_data(cur, &size);
     521                       
     522                        /* N.B.: The generated binary data should be freed */
    407523                        if (data != NULL)
    408524                                free(data);
     
    415531                }
    416532               
     533                /* Recursivelly nest into the subtree */
    417534                switch (cur->subtree_type) {
    418535                case SYSINFO_SUBTREE_NONE:
     
    434551}
    435552
     553/** Dump the structure of sysinfo tree
     554 *
     555 * @param root  Root item of the sysinfo (sub)tree.
     556 *              If it is NULL then consider the global
     557 *              sysinfo tree.
     558 *
     559 */
    436560void sysinfo_dump(sysinfo_item_t *root)
    437561{
     562        /* Avoid other functions to mess with sysinfo
     563           while we are dumping it */
    438564        ipl_t ipl = interrupts_disable();
    439565        spinlock_lock(&sysinfo_lock);
     
    448574}
    449575
    450 /** Return sysinfo item determined by name
     576/** Return sysinfo item value determined by name
    451577 *
    452578 * Should be called with interrupts disabled
    453579 * and sysinfo_lock held.
    454580 *
     581 * @param name Sysinfo path.
     582 * @param root Root item of the sysinfo (sub)tree.
     583 *             If it is NULL then consider the global
     584 *             sysinfo tree.
     585 *
     586 * @return Item value (constant or generated).
     587 *
    455588 */
    456589static sysinfo_return_t sysinfo_get_item(const char *name, sysinfo_item_t **root)
     
    459592                root = &global_root;
    460593       
     594        /* Try to find the item or generate data */
    461595        sysinfo_return_t ret;
    462596        sysinfo_return_t *ret_ptr = &ret;
     
    464598       
    465599        if (item != NULL) {
     600                /* Item found in the fixed sysinfo tree */
     601               
    466602                ret.tag = item->val_type;
    467603                switch (item->val_type) {
     
    482618                }
    483619        } else {
    484                 if (ret_ptr == NULL)
     620                /* No item in the fixed sysinfo tree */
     621                if (ret_ptr == NULL) {
     622                        /* Even no data was generated */
    485623                        ret.tag = SYSINFO_VAL_UNDEFINED;
     624                }
    486625        }
    487626       
     
    492631 *
    493632 * Should be called with interrupts disabled
    494  * and sysinfo_lock held.
     633 * and sysinfo_lock held. The path string passed from
     634 * the user space has to be properly null-terminated
     635 * (the last passed character must be null).
     636 *
     637 * @param ptr  Sysinfo path in the user address space.
     638 * @param size Size of the path string.
    495639 *
    496640 */
     
    514658}
    515659
     660/** Get the sysinfo value type (syscall)
     661 *
     662 * The path string passed from the user space has
     663 * to be properly null-terminated (the last passed
     664 * character must be null).
     665 *
     666 * @param path_ptr  Sysinfo path in the user address space.
     667 * @param path_size Size of the path string.
     668 *
     669 * @return Item value type.
     670 *
     671 */
    516672unative_t sys_sysinfo_get_tag(void *path_ptr, size_t path_size)
    517673{
    518         ipl_t ipl = interrupts_disable();
    519         spinlock_lock(&sysinfo_lock);
    520        
     674        /* Avoid other functions to mess with sysinfo
     675           while we are reading it */
     676        ipl_t ipl = interrupts_disable();
     677        spinlock_lock(&sysinfo_lock);
     678       
     679        /* Get the item */
    521680        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
    522681       
     682        /* N.B.: The generated binary data should be freed */
    523683        if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
    524684                free(ret.data.data);
    525685       
     686        /* Map generated value types to constant types
     687           (user space does not care whether the
     688           value is constant or generated) */
    526689        if (ret.tag == SYSINFO_VAL_FUNCTION_VAL)
    527690                ret.tag = SYSINFO_VAL_VAL;
     
    535698}
    536699
     700/** Get the sysinfo numerical value (syscall)
     701 *
     702 * The path string passed from the user space has
     703 * to be properly null-terminated (the last passed
     704 * character must be null).
     705 *
     706 * @param path_ptr  Sysinfo path in the user address space.
     707 * @param path_size Size of the path string.
     708 * @param value_ptr User space pointer where to store the
     709 *                  numberical value.
     710 *
     711 * @return Error code (EOK in case of no error).
     712 *
     713 */
    537714unative_t sys_sysinfo_get_value(void *path_ptr, size_t path_size,
    538715    void *value_ptr)
    539716{
    540         ipl_t ipl = interrupts_disable();
    541         spinlock_lock(&sysinfo_lock);
    542        
     717        /* Avoid other functions to mess with sysinfo
     718           while we are reading it */
     719        ipl_t ipl = interrupts_disable();
     720        spinlock_lock(&sysinfo_lock);
     721       
     722        /* Get the item */
    543723        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
    544724        int rc;
    545725       
     726        /* Only constant or generated numerical value is returned */
    546727        if ((ret.tag == SYSINFO_VAL_VAL) || (ret.tag == SYSINFO_VAL_FUNCTION_VAL))
    547728                rc = copy_to_uspace(value_ptr, &ret.val, sizeof(ret.val));
     
    549730                rc = EINVAL;
    550731       
     732        /* N.B.: The generated binary data should be freed */
    551733        if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
    552734                free(ret.data.data);
     
    558740}
    559741
     742/** Get the sysinfo binary data size (syscall)
     743 *
     744 * The path string passed from the user space has
     745 * to be properly null-terminated (the last passed
     746 * character must be null).
     747 *
     748 * @param path_ptr  Sysinfo path in the user address space.
     749 * @param path_size Size of the path string.
     750 * @param size_ptr  User space pointer where to store the
     751 *                  binary data size.
     752 *
     753 * @return Error code (EOK in case of no error).
     754 *
     755 */
    560756unative_t sys_sysinfo_get_data_size(void *path_ptr, size_t path_size,
    561757    void *size_ptr)
    562758{
    563         ipl_t ipl = interrupts_disable();
    564         spinlock_lock(&sysinfo_lock);
    565        
     759        /* Avoid other functions to mess with sysinfo
     760           while we are reading it */
     761        ipl_t ipl = interrupts_disable();
     762        spinlock_lock(&sysinfo_lock);
     763       
     764        /* Get the item */
    566765        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
    567766        int rc;
    568767       
     768        /* Only the size of constant or generated binary data is considered */
    569769        if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA))
    570770                rc = copy_to_uspace(size_ptr, &ret.data.size,
     
    573773                rc = EINVAL;
    574774       
     775        /* N.B.: The generated binary data should be freed */
    575776        if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
    576777                free(ret.data.data);
     
    582783}
    583784
     785/** Get the sysinfo binary data (syscall)
     786 *
     787 * The path string passed from the user space has
     788 * to be properly null-terminated (the last passed
     789 * character must be null).
     790 *
     791 * The user space buffer must be sized exactly according
     792 * to the size of the binary data, otherwise the request
     793 * fails.
     794 *
     795 * @param path_ptr    Sysinfo path in the user address space.
     796 * @param path_size   Size of the path string.
     797 * @param buffer_ptr  User space pointer to the buffer where
     798 *                    to store the binary data.
     799 * @param buffer_size User space buffer size.
     800 *
     801 * @return Error code (EOK in case of no error).
     802 *
     803 */
    584804unative_t sys_sysinfo_get_data(void *path_ptr, size_t path_size,
    585805    void *buffer_ptr, size_t buffer_size)
    586806{
    587         ipl_t ipl = interrupts_disable();
    588         spinlock_lock(&sysinfo_lock);
    589        
     807        /* Avoid other functions to mess with sysinfo
     808           while we are reading it */
     809        ipl_t ipl = interrupts_disable();
     810        spinlock_lock(&sysinfo_lock);
     811       
     812        /* Get the item */
    590813        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
    591814        int rc;
    592815       
     816        /* Only constant or generated binary data is considered */
    593817        if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) {
     818                /* Check destination buffer size */
    594819                if (ret.data.size == buffer_size)
    595820                        rc = copy_to_uspace(buffer_ptr, ret.data.data,
     
    600825                rc = EINVAL;
    601826       
     827        /* N.B.: The generated binary data should be freed */
    602828        if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
    603829                free(ret.data.data);
  • uspace/lib/c/generic/stats.c

    rfce3536 r80bfb601  
    4343#define SYSINFO_STATS_MAX_PATH  64
    4444
     45/** Get CPUs statistics
     46 *
     47 * @param count Number of records returned.
     48 *
     49 * @return Array of stats_cpu_t structures.
     50 *         If non-NULL then it should be eventually freed
     51 *         by free().
     52 *
     53 */
    4554stats_cpu_t *get_stats_cpus(size_t *count)
    4655{
     
    5564}
    5665
     66/** Get physical memory statistics
     67 *
     68 *
     69 * @return Pointer to the stats_physmem_t structure.
     70 *         If non-NULL then it should be eventually freed
     71 *         by free().
     72 *
     73 */
    5774stats_physmem_t *get_stats_physmem(void)
    5875{
     
    6683}
    6784
     85/** Get task IDs
     86 *
     87 * @param count Number of IDs returned.
     88 *
     89 * @return Array of IDs (task_id_t).
     90 *         If non-NULL then it should be eventually freed
     91 *         by free().
     92 *
     93 */
    6894task_id_t *get_stats_tasks(size_t *count)
    6995{
     
    78104}
    79105
     106/** Get single task statistics
     107 *
     108 * @param task_id Task ID we are interested in.
     109 *
     110 * @return Pointer to the stats_task_t structure.
     111 *         If non-NULL then it should be eventually freed
     112 *         by free().
     113 *
     114 */
    80115stats_task_t *get_stats_task(task_id_t task_id)
    81116{
     
    92127}
    93128
     129/** Get system load
     130 *
     131 * @param count Number of load records returned.
     132 *
     133 * @return Array of load records (load_t).
     134 *         If non-NULL then it should be eventually freed
     135 *         by free().
     136 *
     137 */
    94138load_t *get_stats_load(size_t *count)
    95139{
     
    104148}
    105149
     150/** Get system uptime
     151 *
     152 * @return System uptime (in seconds).
     153 *
     154 */
    106155sysarg_t get_stats_uptime(void)
    107156{
     
    113162}
    114163
     164/** Print load fixed-point value
     165 *
     166 * Print the load record fixed-point value in decimal
     167 * representation on stdout.
     168 *
     169 * @param upper      Load record.
     170 * @param dec_length Number of decimal digits to print.
     171 *
     172 */
    115173void print_load_fragment(load_t upper, unsigned int dec_length)
    116174{
  • uspace/lib/c/generic/sysinfo.c

    rfce3536 r80bfb601  
    4040#include <bool.h>
    4141
     42/** Get sysinfo item type
     43 *
     44 * @param path Sysinfo path.
     45 *
     46 * @return Sysinfo item type.
     47 *
     48 */
    4249sysinfo_item_tag_t sysinfo_get_tag(const char *path)
    4350{
     
    4653}
    4754
     55/** Get sysinfo numerical value
     56 *
     57 * @param path  Sysinfo path.
     58 * @param value Pointer to store the numerical value to.
     59 *
     60 * @return EOK if the value was successfully read and
     61 *         is of SYSINFO_VAL_VAL type.
     62 *
     63 */
    4864int sysinfo_get_value(const char *path, sysarg_t *value)
    4965{
     
    5268}
    5369
     70/** Get sysinfo binary data size
     71 *
     72 * @param path  Sysinfo path.
     73 * @param value Pointer to store the binary data size.
     74 *
     75 * @return EOK if the value was successfully read and
     76 *         is of SYSINFO_VAL_DATA type.
     77 *
     78 */
    5479static int sysinfo_get_data_size(const char *path, size_t *size)
    5580{
     
    5883}
    5984
     85/** Get sysinfo binary data
     86 *
     87 * @param path  Sysinfo path.
     88 * @param value Pointer to store the binary data size.
     89 *
     90 * @return Binary data read from sysinfo or NULL if the
     91 *         sysinfo item value type is not binary data.
     92 *         The returned non-NULL pointer should be
     93 *         freed by free().
     94 *
     95 */
    6096void *sysinfo_get_data(const char *path, size_t *size)
    6197{
     98        /* The binary data size might change during time.
     99           Unfortunatelly we cannot allocate the buffer
     100           and transfer the data as a single atomic operation.
     101       
     102           Let's hope that the number of iterations is bounded
     103           in common cases. */
     104       
    62105        while (true) {
     106                /* Get the binary data size */
    63107                int ret = sysinfo_get_data_size(path, size);
    64                 if (ret != EOK)
     108                if (ret != EOK) {
     109                        /* Not binary data item */
    65110                        return NULL;
     111                }
    66112               
    67113                void *data = malloc(*size);
     
    69115                        return NULL;
    70116               
     117                /* Get the data */
    71118                ret = __SYSCALL4(SYS_SYSINFO_GET_DATA, (sysarg_t) path,
    72119                    (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size);
     
    74121                        return data;
    75122               
     123                /* Dispose the buffer */
    76124                free(data);
    77125               
    78                 if (ret != ENOMEM)
     126                if (ret != ENOMEM) {
     127                        /* The failure to get the data was not caused
     128                           by wrong buffer size */
    79129                        return NULL;
     130                }
    80131        }
    81132}
  • uspace/lib/c/include/sysinfo.h

    rfce3536 r80bfb601  
    3838#include <libc.h>
    3939
     40/** Sysinfo value types
     41 *
     42 */
    4043typedef enum {
    4144        SYSINFO_VAL_UNDEFINED = 0,
Note: See TracChangeset for help on using the changeset viewer.