summaryrefslogtreecommitdiff
path: root/src/modules/cpu.c
blob: cf705241f17f695075be0929083ace51ef6ae72e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "cpu.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
#include <tgmath.h>

#define VALUE_SIZE 32

#define FILE_STAT_PATH "/proc/stat"

struct cpu_stat {
    unsigned long usage;
    unsigned long total;
};

struct cpu {
    char value[VALUE_SIZE];

    struct cpu_stat last;
    FILE * statfd;
};

static void
parse_cpu_stat(struct cpu * c, struct cpu_stat * stat)
{
    char line[1024];
    char * tok = line + 5;

    stat->usage = 0;
    stat->total = 0;

    rewind(c->statfd);
    fflush(c->statfd);
    fgets(line, 1024, c->statfd);

    stat->usage += strtoul(tok, &tok, 10);
    stat->usage += strtoul(tok, &tok, 10);
    stat->usage += strtoul(tok, &tok, 10);
    stat->total += stat->usage + strtoul(tok, &tok, 10);
}

struct cpu *
cpu_new()
{
    struct cpu * c = malloc(sizeof(struct cpu));
    memset(c->value, '\0', VALUE_SIZE);
    c->statfd = fopen(FILE_STAT_PATH, "r");

    parse_cpu_stat(c, &c->last);

    return c;
}

void
cpu_free(struct cpu * c)
{
    fclose(c->statfd);
    free(c);
}

void
cpu_update(struct cpu * c)
{
    struct cpu_stat stat;
    unsigned long usage_diff, total_diff;

    unsigned short percent;

    parse_cpu_stat(c, &stat);

    usage_diff = stat.usage - c->last.usage;
    total_diff = stat.total - c->last.total;

    c->last = stat;

    percent = round((100.0f / total_diff) * usage_diff);

    snprintf(c->value, VALUE_SIZE, "\uf2db% 4d%%", percent);
}

const char *
cpu_get_val(struct cpu * c)
{
    return c->value;
}