skip to content
==> tests/cpuuse.c <==
1/* cpuuse.rs's meter_counts_this_threads_cpu_and_memory. */
2#include "mesh/check.h"
3#include "mesh/cpuuse.h"
4
5#include <pthread.h>
6#include <time.h>
7
8static double ms_since(const struct timespec *t0) {
9    struct timespec t;
10    clock_gettime(CLOCK_MONOTONIC, &t);
11    return (double)(t.tv_sec - t0->tv_sec) * 1e3 + (double)(t.tv_nsec - t0->tv_nsec) / 1e6;
12}
13
14static void *lane(void *arg) {
15    (void)arg;
16    mesh_meter m;
17    mesh_meter_start(&m, 31);
18    uint64_t cpu, rss;
19    uint32_t units;
20    mesh_slot_use_get(&mesh_cpuuse_slots[31], &cpu, &rss, &units);
21    CHECK_U(units, 1);
22    /* 30 ms of this thread's CPU (the Rust spins 30 ms of wall time, which a
23     * loaded machine may not turn into 20 ms of CPU); at most 10 s of wall. */
24    struct timespec t0;
25    clock_gettime(CLOCK_MONOTONIC, &t0);
26    uint64_t c0 = mesh_thread_cpu_ns();
27    volatile uint64_t x = 0;
28    while (mesh_thread_cpu_ns() - c0 < 30000000u && ms_since(&t0) < 10000) x = x * 31 + 7;
29    mesh_meter_tick(&m, 1u << 20);
30    mesh_slot_use_get(&mesh_cpuuse_slots[31], &cpu, &rss, &units);
31    CHECK(cpu >= 20000000);
32    CHECK_U(rss, 1u << 20);
33    CHECK_U(units, 1);
34    mesh_meter_tick(&m, 3u << 20);
35    mesh_slot_use_get(&mesh_cpuuse_slots[31], &cpu, &rss, &units);
36    CHECK_U(rss, 3u << 20);
37    mesh_meter_end(&m);
38    return NULL;
39}
40
41int main(void) {
42    pthread_t t;
43    pthread_create(&t, NULL, lane, NULL);
44    pthread_join(t, NULL);
45    uint64_t cpu, rss;
46    uint32_t units;
47    mesh_slot_use_get(&mesh_cpuuse_slots[31], &cpu, &rss, &units);
48    CHECK(cpu < 200000000);
49    CHECK_U(rss, 0);
50    CHECK_U(units, 0);
51    return mesh_check_done();
52}