Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 70e2b2d in mainline


Ignore:
Timestamp:
2010-04-18T10:23:15Z (12 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
c3d4bb4
Parents:
da98918
Message:

avoid costly allocation and generation of data when it is actually not necessary

Files:
4 edited

Legend:

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

    rda98918 r70e2b2d  
    6868
    6969/** Generated binary data function */
    70 typedef void *(*sysinfo_fn_data_t)(struct sysinfo_item *, size_t *);
     70typedef void *(*sysinfo_fn_data_t)(struct sysinfo_item *, size_t *, bool);
    7171
    7272/** Sysinfo item binary data
  • kernel/generic/src/sysinfo/stats.c

    rda98918 r70e2b2d  
    8585/** Get statistics of all CPUs
    8686 *
    87  * @param item Sysinfo item (unused).
    88  * @param size Size of the returned data.
     87 * @param item    Sysinfo item (unused).
     88 * @param size    Size of the returned data.
     89 * @param dry_run Do not get the data, just calculate the size.
    8990 *
    9091 * @return Data containing several stats_cpu_t structures.
     
    9293 *         in the context of the sysinfo request.
    9394 */
    94 static void *get_stats_cpus(struct sysinfo_item *item, size_t *size)
    95 {
     95static void *get_stats_cpus(struct sysinfo_item *item, size_t *size,
     96    bool dry_run)
     97{
     98        *size = sizeof(stats_cpu_t) * config.cpu_count;
     99        if (dry_run)
     100                return NULL;
     101       
    96102        /* Assumption: config.cpu_count is constant */
    97         stats_cpu_t *stats_cpus =
    98             (stats_cpu_t *) malloc(sizeof(stats_cpu_t) * config.cpu_count,
    99             FRAME_ATOMIC);
     103        stats_cpu_t *stats_cpus = (stats_cpu_t *) malloc(*size, FRAME_ATOMIC);
    100104        if (stats_cpus == NULL) {
    101105                *size = 0;
     
    120124        interrupts_restore(ipl);
    121125       
    122         *size = sizeof(stats_cpu_t) * config.cpu_count;
    123126        return ((void *) stats_cpus);
    124127}
     
    172175/** Get task IDs
    173176 *
    174  * @param item Sysinfo item (unused).
    175  * @param size Size of the returned data.
     177 * @param item    Sysinfo item (unused).
     178 * @param size    Size of the returned data.
     179 * @param dry_run Do not get the data, just calculate the size.
    176180 *
    177181 * @return Data containing task IDs of all tasks.
     
    179183 *         in the context of the sysinfo request.
    180184 */
    181 static void *get_stats_tasks(struct sysinfo_item *item, size_t *size)
     185static void *get_stats_tasks(struct sysinfo_item *item, size_t *size,
     186    bool dry_run)
    182187{
    183188        /* Messing with task structures, avoid deadlock */
     
    198203        }
    199204       
    200         task_id_t *task_ids =
    201             (task_id_t *) malloc(sizeof(task_id_t) * count, FRAME_ATOMIC);
     205        *size = sizeof(task_id_t) * count;
     206        if (dry_run) {
     207                spinlock_unlock(&tasks_lock);
     208                interrupts_restore(ipl);
     209                return NULL;
     210        }
     211       
     212        task_id_t *task_ids = (task_id_t *) malloc(*size, FRAME_ATOMIC);
    202213        if (task_ids == NULL) {
    203214                /* No free space for allocation */
     
    216227        interrupts_restore(ipl);
    217228       
    218         *size = sizeof(task_id_t) * count;
    219229        return ((void *) task_ids);
    220230}
     
    326336/** Get physical memory statistics
    327337 *
    328  * @param item Sysinfo item (unused).
    329  * @param size Size of the returned data.
     338 * @param item    Sysinfo item (unused).
     339 * @param size    Size of the returned data.
     340 * @param dry_run Do not get the data, just calculate the size.
    330341 *
    331342 * @return Data containing stats_physmem_t.
     
    333344 *         in the context of the sysinfo request.
    334345 */
    335 static void *get_stats_physmem(struct sysinfo_item *item, size_t *size)
    336 {
     346static void *get_stats_physmem(struct sysinfo_item *item, size_t *size,
     347    bool dry_run)
     348{
     349        *size = sizeof(stats_physmem_t);
     350        if (dry_run)
     351                return NULL;
     352       
    337353        stats_physmem_t *stats_physmem =
    338             (stats_physmem_t *) malloc(sizeof(stats_physmem_t), FRAME_ATOMIC);
     354            (stats_physmem_t *) malloc(*size, FRAME_ATOMIC);
    339355        if (stats_physmem == NULL) {
    340356                *size = 0;
     
    345361            &(stats_physmem->used), &(stats_physmem->free));
    346362       
    347         *size = sizeof(stats_physmem_t);
    348363        return ((void *) stats_physmem);
    349364}
     
    351366/** Get system load
    352367 *
    353  * @param item Sysinfo item (unused).
    354  * @param size Size of the returned data.
     368 * @param item    Sysinfo item (unused).
     369 * @param size    Size of the returned data.
     370 * @param dry_run Do not get the data, just calculate the size.
    355371 *
    356372 * @return Data several load_t values.
     
    358374 *         in the context of the sysinfo request.
    359375 */
    360 static void *get_stats_load(struct sysinfo_item *item, size_t *size)
    361 {
    362         load_t *stats_load =
    363             (load_t *) malloc(sizeof(load_t) * LOAD_STEPS, FRAME_ATOMIC);
     376static void *get_stats_load(struct sysinfo_item *item, size_t *size,
     377    bool dry_run)
     378{
     379        *size = sizeof(load_t) * LOAD_STEPS;
     380        if (dry_run)
     381                return NULL;
     382       
     383        load_t *stats_load = (load_t *) malloc(*size, FRAME_ATOMIC);
    364384        if (stats_load == NULL) {
    365385                *size = 0;
     
    378398        interrupts_restore(ipl);
    379399       
    380         *size = sizeof(load_t) * LOAD_STEPS;
    381400        return ((void *) stats_load);
    382401}
  • kernel/generic/src/sysinfo/sysinfo.c

    rda98918 r70e2b2d  
    496496               
    497497                unative_t val;
    498                 void *data;
    499498                size_t size;
    500499               
     
    518517                        break;
    519518                case SYSINFO_VAL_FUNCTION_DATA:
    520                         data = cur->val.fn_data(cur, &size);
    521                        
    522                         /* N.B.: The generated binary data should be freed */
    523                         if (data != NULL)
    524                                 free(data);
    525                        
     519                        /* N.B.: No data was actually returned (only a dry run) */
     520                        (void) cur->val.fn_data(cur, &size, true);
    526521                        printf("+ %s (%" PRIs" bytes) [generated]\n", cur->name,
    527522                            size);
     
    579574 * and sysinfo_lock held.
    580575 *
    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.
     576 * @param name    Sysinfo path.
     577 * @param root    Root item of the sysinfo (sub)tree.
     578 *                If it is NULL then consider the global
     579 *                sysinfo tree.
     580 * @param dry_run Do not actually get any generated
     581 *                binary data, just calculate the size.
    585582 *
    586583 * @return Item value (constant or generated).
    587584 *
    588585 */
    589 static sysinfo_return_t sysinfo_get_item(const char *name, sysinfo_item_t **root)
     586static sysinfo_return_t sysinfo_get_item(const char *name,
     587    sysinfo_item_t **root, bool dry_run)
    590588{
    591589        if (root == NULL)
     
    614612                        break;
    615613                case SYSINFO_VAL_FUNCTION_DATA:
    616                         ret.data.data = item->val.fn_data(item, &ret.data.size);
     614                        ret.data.data = item->val.fn_data(item, &ret.data.size,
     615                            dry_run);
    617616                        break;
    618617                }
     
    635634 * (the last passed character must be null).
    636635 *
    637  * @param ptr  Sysinfo path in the user address space.
    638  * @param size Size of the path string.
    639  *
    640  */
    641 static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size)
     636 * @param ptr     Sysinfo path in the user address space.
     637 * @param size    Size of the path string.
     638 * @param dry_run Do not actually get any generated
     639 *                binary data, just calculate the size.
     640 *
     641 */
     642static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size,
     643    bool dry_run)
    642644{
    643645        sysinfo_return_t ret;
     
    652654        if ((copy_from_uspace(path, ptr, size + 1) == 0)
    653655            && (path[size] == 0))
    654                 ret = sysinfo_get_item(path, NULL);
     656                ret = sysinfo_get_item(path, NULL, dry_run);
    655657       
    656658        free(path);
     
    677679        spinlock_lock(&sysinfo_lock);
    678680       
    679         /* Get the item */
    680         sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
    681        
    682         /* N.B.: The generated binary data should be freed */
    683         if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
    684                 free(ret.data.data);
     681        /* Get the item.
     682       
     683           N.B.: There is no need to free any potential generated
     684           binary data since we request a dry run */
     685        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
    685686       
    686687        /* Map generated value types to constant types
     
    720721        spinlock_lock(&sysinfo_lock);
    721722       
    722         /* Get the item */
    723         sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
     723        /* Get the item.
     724       
     725           N.B.: There is no need to free any potential generated
     726           binary data since we request a dry run */
     727        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
    724728        int rc;
    725729       
     
    730734                rc = EINVAL;
    731735       
    732         /* N.B.: The generated binary data should be freed */
    733         if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
    734                 free(ret.data.data);
    735        
    736736        spinlock_unlock(&sysinfo_lock);
    737737        interrupts_restore(ipl);
     
    762762        spinlock_lock(&sysinfo_lock);
    763763       
    764         /* Get the item */
    765         sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
     764        /* Get the item.
     765       
     766           N.B.: There is no need to free any potential generated
     767           binary data since we request a dry run */
     768        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, true);
    766769        int rc;
    767770       
     
    773776                rc = EINVAL;
    774777       
    775         /* N.B.: The generated binary data should be freed */
    776         if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL))
    777                 free(ret.data.data);
    778        
    779778        spinlock_unlock(&sysinfo_lock);
    780779        interrupts_restore(ipl);
     
    811810       
    812811        /* Get the item */
    813         sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size);
     812        sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size, false);
    814813        int rc;
    815814       
  • uspace/app/uptime/uptime.c

    rda98918 r70e2b2d  
    3939#include <sys/time.h>
    4040#include <inttypes.h>
     41#include <malloc.h>
    4142
    4243#define NAME  "uptime"
     
    7475                        print_load_fragment(load[i], 2);
    7576                }
     77               
     78                free(load);
    7679        }
    7780       
Note: See TracChangeset for help on using the changeset viewer.