summaryrefslogtreecommitdiffstats
path: root/src/detection/cpuusage/cpuusage_bsd.c
blob: f690d15d4312791131300ced39010f5c4d372c48 (plain) (blame)
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
#include "detection/cpuusage/cpuusage.h"
#include "common/mallocHelper.h"

#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
#include <stdlib.h>

#if __OpenBSD__ || __NetBSD__
    #include <sys/sched.h>
#endif

const char* ffGetCpuUsageInfo(FFlist* cpuTimes) {
    size_t neededLength = 0;
#if __OpenBSD__ || __NetBSD__
    #ifdef KERN_CPTIME
    int ctls[] = { CTL_KERN, KERN_CPTIME };
    #else
    int ctls[] = { CTL_KERN, KERN_CP_TIME };
    #endif
    if (sysctl(ctls, 2, NULL, &neededLength, NULL, 0) != 0) {
        return "sysctl({CTL_KERN, KERN_CPTIME}, 2, NULL) failed";
    }
#else
    if (sysctlbyname("kern.cp_times", NULL, &neededLength, NULL, 0) != 0) {
        return "sysctlbyname(kern.cp_times, NULL) failed";
    }
#endif

    uint32_t coreCount = (uint32_t) (neededLength / (CPUSTATES * sizeof(uint64_t)));
    assert(coreCount > 0);

    FF_AUTO_FREE uint64_t (*cpTimes)[CPUSTATES] = malloc(neededLength);

#if __OpenBSD__ || __NetBSD__
    if (sysctl(ctls, 2, cpTimes, &neededLength, NULL, 0) != 0) {
        return "sysctl({CTL_KERN, KERN_CPTIME}, 2, NULL) failed";
    }
#else
    if (sysctlbyname("kern.cp_times", cpTimes, &neededLength, NULL, 0) != 0) {
        return "sysctlbyname(kern.cp_times, cpTime) failed";
    }
#endif

    for (uint32_t i = 0; i < coreCount; ++i) {
        uint64_t* cpTime = cpTimes[i];
        uint64_t inUse = cpTime[CP_USER] + cpTime[CP_NICE] + cpTime[CP_SYS] + cpTime[CP_INTR];
        uint64_t total = inUse + cpTime[CP_IDLE];

        FFCpuUsageInfo* info = FF_LIST_ADD(FFCpuUsageInfo, *cpuTimes);
        *info = (FFCpuUsageInfo) {
            .inUseAll = inUse,
            .totalAll = total,
        };
    }

    return NULL;
}