Ejemplo n.º 1
0
static gboolean
cpu_update(Monitor * c)
{
    static struct cpu_stat previous_cpu_stat = { 0, 0, 0, 0 };

    if ((c->stats != NULL) && (c->pixmap != NULL))
    {
        /* Open statistics file and scan out CPU usage. */
        struct cpu_stat cpu;
        FILE * stat = fopen("/proc/stat", "r");
        if (stat == NULL)
            return TRUE;
        int fscanf_result = fscanf(stat, "cpu %lu %lu %lu %lu", 
                                    &cpu.u, &cpu.n, &cpu.s, &cpu.i);
        fclose(stat);

        /* Ensure that fscanf succeeded. */
        if (fscanf_result == 4)
        {
            /* Comcolors delta from previous statistics. */
            struct cpu_stat cpu_delta;
            cpu_delta.u = cpu.u - previous_cpu_stat.u;
            cpu_delta.n = cpu.n - previous_cpu_stat.n;
            cpu_delta.s = cpu.s - previous_cpu_stat.s;
            cpu_delta.i = cpu.i - previous_cpu_stat.i;

            /* Copy current to previous. */
            memcpy(&previous_cpu_stat, &cpu, sizeof(struct cpu_stat));

            /* Comcolors user+nice+system as a fraction of total.
             * Introduce this sample to ring buffer, increment and wrap ring
             * buffer cursor. */
            float cpu_uns = cpu_delta.u + cpu_delta.n + cpu_delta.s;
            c->stats[c->ring_cursor] = cpu_uns / (cpu_uns + cpu_delta.i);
            c->ring_cursor += 1;
            if (c->ring_cursor >= c->pixmap_width)
                c->ring_cursor = 0;

            /* Redraw with the new sample. */
            redraw_pixmap(c);
        }
    }
    return TRUE;
}
Ejemplo n.º 2
0
/******************************************************************************
 *                            Basic events handlers                           *
 ******************************************************************************/
static gboolean
configure_event(GtkWidget* widget, GdkEventConfigure* dummy, gpointer data) 
{
    (void) dummy;

    int new_pixmap_width, new_pixmap_height;

    new_pixmap_width = widget->allocation.width - BORDER_SIZE * 2;
    new_pixmap_height = widget->allocation.height - BORDER_SIZE *2;
    Monitor *m;

    m = (Monitor *) data;

    if (new_pixmap_width > 0 && new_pixmap_height > 0)
    {
        /*
         * If the stats buffer does not exist (first time we get inside this
         * function) or its size changed, reallocate the buffer and preserve
         * existing data.
         */
        if (!m->stats || (new_pixmap_width != m->pixmap_width))
        {
            stats_set *new_stats = g_new0(stats_set, new_pixmap_width);
            
            if (!new_stats)
                return TRUE;

            if (m->stats)
            {
                /* New allocation is larger.
                 * Add new "oldest" samples of zero following the cursor*/
                if (new_pixmap_width > m->pixmap_width)
                {
                    /* Number of values between the ring cursor and the end of
                     * the buffer */
                    int nvalues = m->pixmap_width - m->ring_cursor;

                    memcpy(new_stats,
                           m->stats,
                           m->ring_cursor * sizeof (stats_set));
                    memcpy(new_stats + nvalues,
                           m->stats + m->ring_cursor,
                           nvalues * sizeof(stats_set));
                }
                /* New allocation is smaller, but still larger than the ring
                 * buffer cursor */
                else if (m->ring_cursor <= new_pixmap_width)
                {
                    /* Numver of values that can be stored between the end of
                     * the new buffer and the ring cursor */
                    int nvalues = new_pixmap_width - m->ring_cursor;
                    memcpy(new_stats,
                           m->stats,
                           m->ring_cursor * sizeof(stats_set));
                    memcpy(new_stats + m->ring_cursor,
                           m->stats + m->pixmap_width - nvalues,
                           nvalues * sizeof(stats_set));
                }
                /* New allocation is smaller, and also smaller than the ring
                 * buffer cursor.  Discard all oldest samples following the ring 
                 * buffer cursor and additional samples at the beginning of the 
                 * buffer. */
                else
                {
                    memcpy(new_stats,
                           m->stats + m->ring_cursor - new_pixmap_width,
                           new_pixmap_width * sizeof(stats_set));
                }
                g_free(m->stats);
            }
            m->stats = new_stats;
        }

        m->pixmap_width = new_pixmap_width;
        m->pixmap_height = new_pixmap_height;
        if (m->pixmap)
            cairo_surface_destroy(m->pixmap);
        m->pixmap = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
                                   m->pixmap_width,
                                   m->pixmap_height);
        check_cairo_surface_status(&m->pixmap);
        redraw_pixmap(m);
    }
    
    return TRUE;
}
Ejemplo n.º 3
0
/******************************************************************************
 *                               RAM Monitor                                  *
 ******************************************************************************/
static gboolean
mem_update(Monitor * m)
{
    ENTER; 

    FILE *meminfo;
    int mem_total = 0;
    int mem_free  = 0;
    int mem_buffers = 0;
    int mem_cached = 0;

    if (m->stats && m->pixmap)
    {
        meminfo = fopen("/proc/meminfo", "r");
        if (!meminfo)
            RET(FALSE);

        if (fscanf(meminfo, "MemTotal: %d kB\n", &mem_total) != 1) {
            fclose (meminfo);
            RET(FALSE);
        }
        if (fscanf(meminfo, "MemFree: %d kB\n", &mem_free) != 1) {
            fclose (meminfo);
            RET(FALSE);
        }
        if (fscanf(meminfo, "Buffers: %d kB\n", &mem_buffers) != 1) {
            fclose (meminfo);
            RET(FALSE);
        }
        if (fscanf(meminfo, "Cached: %d kB\n", &mem_cached) != 1) {
            fclose (meminfo);
            RET(FALSE);
        }

        fclose(meminfo);

        m->total = mem_total;

        /* Adding stats to the buffer:
         * It is debatable if 'mem_buffers' counts as free or not. I'll go with
         * 'free', because it can be flushed fairly quickly, and generally
         * isn't necessary to keep in memory.
         * It is hard to draw the line, which caches should be counted as free,
         * and which not. Pagecaches, dentry, and inode caches are quickly
         * filled up again for almost any use case. Hence I would not count
         * them as 'free'.
         * 'mem_cached' definitely counts as 'free' because it is immediately
         * released should any application need it. */
        m->stats[m->ring_cursor] = (mem_total - mem_buffers - mem_free -
                mem_cached) / (float)mem_total; m->ring_cursor++;

        if (m->ring_cursor >= m->pixmap_width)
            m->ring_cursor = 0; 


        /* Redraw the pixmap, with the new sample */
        redraw_pixmap (m);
    }

    RET(TRUE);
}
Ejemplo n.º 4
0
/******************************************************************************
 *                               RAM Monitor                                  *
 ******************************************************************************/
static gboolean
mem_update(Monitor * m)
{
    ENTER;

    FILE *meminfo;
    char buf[80];
    long int mem_total = 0;
    long int mem_free  = 0;
    long int mem_buffers = 0;
    long int mem_cached = 0;
    unsigned int readmask = 0x8 | 0x4 | 0x2 | 0x1;

    if (!m->stats || !m->pixmap)
        RET(TRUE);

    meminfo = fopen("/proc/meminfo", "r");
    if (!meminfo) {
        g_warning("monitors: Could not open /proc/meminfo: %d, %s",
                  errno, strerror(errno));
        RET(FALSE);
    }

    while (readmask && fgets(buf, sizeof(buf), meminfo)) {
        if (sscanf(buf, "MemTotal: %ld kB\n", &mem_total) == 1) {
            readmask ^= 0x1;
            continue;
        }
        if (sscanf(buf, "MemFree: %ld kB\n", &mem_free) == 1) {
            readmask ^= 0x2;
            continue;
        }
        if (sscanf(buf, "Buffers: %ld kB\n", &mem_buffers) == 1) {
            readmask ^= 0x4;
            continue;
        }
        if (sscanf(buf, "Cached: %ld kB\n", &mem_cached) == 1) {
            readmask ^= 0x8;
            continue;
        }
    }

    fclose(meminfo);

    if (readmask) {
        g_warning("monitors: Couldn't read all values from /proc/meminfo: "
                  "readmask %x", readmask);
        RET(FALSE);
    }

    m->total = mem_total;

    /* Adding stats to the buffer:
     * It is debatable if 'mem_buffers' counts as free or not. I'll go with
     * 'free', because it can be flushed fairly quickly, and generally
     * isn't necessary to keep in memory.
     * It is hard to draw the line, which caches should be counted as free,
     * and which not. Pagecaches, dentry, and inode caches are quickly
     * filled up again for almost any use case. Hence I would not count
     * them as 'free'.
     * 'mem_cached' definitely counts as 'free' because it is immediately
     * released should any application need it. */
    m->stats[m->ring_cursor] = (mem_total - mem_buffers - mem_free -
            mem_cached) / (float)mem_total;

    m->ring_cursor++;
    if (m->ring_cursor >= m->pixmap_width)
        m->ring_cursor = 0;

    /* Redraw the pixmap, with the new sample */
    redraw_pixmap (m);

    RET(TRUE);
}