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)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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);
Note: See TracChangeset for help on using the changeset viewer.