HelenOS sources

root/uspace/lib/c/generic/stats.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. stats_get_cpus
  2. stats_get_physmem
  3. stats_get_tasks
  4. stats_get_task
  5. stats_get_threads
  6. stats_get_ipccs
  7. stats_get_exceptions
  8. stats_get_exception
  9. stats_get_load
  10. stats_print_load_fragment
  11. thread_get_state

/*
 * Copyright (c) 2010 Stanislav Kozina
 * Copyright (c) 2010 Martin Decky
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** @addtogroup libc
 * @{
 */
/** @file
 */

#include <stats.h>
#include <sysinfo.h>
#include <errno.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>

#define SYSINFO_STATS_MAX_PATH  64

/** Thread states
 *
 */
static const char *thread_states[] = {
        "Invalid",
        "Running",
        "Sleeping",
        "Ready",
        "Entering",
        "Exiting",
        "Lingering"
};

/** Get CPUs statistics
 *
 * @param count Number of records returned.
 *
 * @return Array of stats_cpu_t structures.
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
stats_cpu_t *stats_get_cpus(size_t *count)
{
        size_t size = 0;
        stats_cpu_t *stats_cpus =
            (stats_cpu_t *) sysinfo_get_data("system.cpus", &size);

        if ((size % sizeof(stats_cpu_t)) != 0) {
                if (stats_cpus != NULL)
                        free(stats_cpus);
                *count = 0;
                return NULL;
        }

        *count = size / sizeof(stats_cpu_t);
        return stats_cpus;
}

/** Get physical memory statistics
 *
 *
 * @return Pointer to the stats_physmem_t structure.
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
stats_physmem_t *stats_get_physmem(void)
{
        size_t size = 0;
        stats_physmem_t *stats_physmem =
            (stats_physmem_t *) sysinfo_get_data("system.physmem", &size);

        if (size != sizeof(stats_physmem_t)) {
                if (stats_physmem != NULL)
                        free(stats_physmem);
                return NULL;
        }

        return stats_physmem;
}

/** Get task statistics
 *
 * @param count Number of records returned.
 *
 * @return Array of stats_task_t structures.
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
stats_task_t *stats_get_tasks(size_t *count)
{
        size_t size = 0;
        stats_task_t *stats_tasks =
            (stats_task_t *) sysinfo_get_data("system.tasks", &size);

        if ((size % sizeof(stats_task_t)) != 0) {
                if (stats_tasks != NULL)
                        free(stats_tasks);
                *count = 0;
                return NULL;
        }

        *count = size / sizeof(stats_task_t);
        return stats_tasks;
}

/** Get single task statistics
 *
 * @param task_id Task ID we are interested in.
 *
 * @return Pointer to the stats_task_t structure.
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
stats_task_t *stats_get_task(task_id_t task_id)
{
        char name[SYSINFO_STATS_MAX_PATH];
        snprintf(name, SYSINFO_STATS_MAX_PATH, "system.tasks.%" PRIu64, task_id);

        size_t size = 0;
        stats_task_t *stats_task =
            (stats_task_t *) sysinfo_get_data(name, &size);

        if (size != sizeof(stats_task_t)) {
                if (stats_task != NULL)
                        free(stats_task);
                return NULL;
        }

        return stats_task;
}

/** Get thread statistics.
 *
 * @param count Number of records returned.
 *
 * @return Array of stats_thread_t structures.
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
stats_thread_t *stats_get_threads(size_t *count)
{
        size_t size = 0;
        stats_thread_t *stats_threads =
            (stats_thread_t *) sysinfo_get_data("system.threads", &size);

        if ((size % sizeof(stats_thread_t)) != 0) {
                if (stats_threads != NULL)
                        free(stats_threads);
                *count = 0;
                return NULL;
        }

        *count = size / sizeof(stats_thread_t);
        return stats_threads;
}

/** Get IPC connections statistics.
 *
 * @param count Number of records returned.
 *
 * @return Array of stats_ipcc_t structures.
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
stats_ipcc_t *stats_get_ipccs(size_t *count)
{
        size_t size = 0;
        stats_ipcc_t *stats_ipccs =
            (stats_ipcc_t *) sysinfo_get_data("system.ipccs", &size);

        if ((size % sizeof(stats_ipcc_t)) != 0) {
                if (stats_ipccs != NULL)
                        free(stats_ipccs);
                *count = 0;
                return NULL;
        }

        *count = size / sizeof(stats_ipcc_t);
        return stats_ipccs;
}

/** Get exception statistics.
 *
 * @param count Number of records returned.
 *
 * @return Array of stats_exc_t structures.
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
stats_exc_t *stats_get_exceptions(size_t *count)
{
        size_t size = 0;
        stats_exc_t *stats_exceptions =
            (stats_exc_t *) sysinfo_get_data("system.exceptions", &size);

        if ((size % sizeof(stats_exc_t)) != 0) {
                if (stats_exceptions != NULL)
                        free(stats_exceptions);
                *count = 0;
                return NULL;
        }

        *count = size / sizeof(stats_exc_t);
        return stats_exceptions;
}

/** Get single exception statistics
 *
 * @param excn Exception number we are interested in.
 *
 * @return Pointer to the stats_exc_t structure.
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
stats_exc_t *stats_get_exception(unsigned int excn)
{
        char name[SYSINFO_STATS_MAX_PATH];
        snprintf(name, SYSINFO_STATS_MAX_PATH, "system.exceptions.%u", excn);

        size_t size = 0;
        stats_exc_t *stats_exception =
            (stats_exc_t *) sysinfo_get_data(name, &size);

        if (size != sizeof(stats_exc_t)) {
                if (stats_exception != NULL)
                        free(stats_exception);
                return NULL;
        }

        return stats_exception;
}

/** Get system load
 *
 * @param count Number of load records returned.
 *
 * @return Array of load records (load_t).
 *         If non-NULL then it should be eventually freed
 *         by free().
 *
 */
load_t *stats_get_load(size_t *count)
{
        size_t size = 0;
        load_t *load =
            (load_t *) sysinfo_get_data("system.load", &size);

        if ((size % sizeof(load_t)) != 0) {
                if (load != NULL)
                        free(load);
                *count = 0;
                return NULL;
        }

        *count = size / sizeof(load_t);
        return load;
}

/** Print load fixed-point value
 *
 * Print the load record fixed-point value in decimal
 * representation on stdout.
 *
 * @param upper      Load record.
 * @param dec_length Number of decimal digits to print.
 *
 */
void stats_print_load_fragment(load_t upper, unsigned int dec_length)
{
        /* Print the whole part */
        printf("%u.", upper / LOAD_UNIT);

        load_t rest = (upper % LOAD_UNIT) * 10;

        unsigned int i;
        for (i = 0; i < dec_length; i++) {
                printf("%u", rest / LOAD_UNIT);
                rest = (rest % LOAD_UNIT) * 10;
        }
}

const char *thread_get_state(state_t state)
{
        if (state <= Lingering)
                return thread_states[state];

        return thread_states[Invalid];
}

/** @}
 */

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub