==> src/cpuuse.c <==1/* cpuuse.rs: per-slot counters and the per-thread meter. */
2#include "mesh/cpuuse.h"
3
4#include <time.h>
5
6mesh_slot_use mesh_cpuuse_slots[MESH_PROG_SLOTS];
7_Atomic uint32_t mesh_cpuuse_workers, mesh_cpuuse_worker_spawns, mesh_cpuuse_worker_crashes;
8
9void mesh_slot_use_add_cpu(mesh_slot_use *u, uint64_t ns) { atomic_fetch_add_explicit(&u->cpu_ns, ns, memory_order_relaxed); }
10
11void mesh_slot_use_add_rss(mesh_slot_use *u, int64_t d) {
12 if (d >= 0) {
13 atomic_fetch_add_explicit(&u->rss, (uint64_t)d, memory_order_relaxed);
14 return;
15 }
16 uint64_t sub = (uint64_t)(-d), cur = atomic_load_explicit(&u->rss, memory_order_relaxed);
17 while (!atomic_compare_exchange_weak_explicit(&u->rss, &cur, cur > sub ? cur - sub : 0, memory_order_relaxed,
18 memory_order_relaxed)) {
19 }
20}
21
22void mesh_slot_use_get(mesh_slot_use *u, uint64_t *cpu_ns, uint64_t *rss, uint32_t *units) {
23 *cpu_ns = atomic_load_explicit(&u->cpu_ns, memory_order_relaxed);
24 *rss = atomic_load_explicit(&u->rss, memory_order_relaxed);
25 *units = atomic_load_explicit(&u->units, memory_order_relaxed);
26}
27
28uint64_t mesh_thread_cpu_ns(void) {
29 struct timespec ts = {0, 0};
30 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
31 return (uint64_t)ts.tv_sec * 1000000000u + (uint64_t)ts.tv_nsec;
32}
33
34void mesh_meter_start(mesh_meter *m, uint32_t slot) {
35 atomic_fetch_add_explicit(&mesh_cpuuse_slots[slot].units, 1, memory_order_relaxed);
36 *m = (mesh_meter){slot, mesh_thread_cpu_ns(), 0};
37}
38
39void mesh_meter_tick(mesh_meter *m, uint64_t rss) {
40 uint64_t now = mesh_thread_cpu_ns();
41 mesh_slot_use *u = &mesh_cpuuse_slots[m->slot];
42 mesh_slot_use_add_cpu(u, now > m->cpu ? now - m->cpu : 0);
43 m->cpu = now;
44 if (rss != m->rss) {
45 mesh_slot_use_add_rss(u, (int64_t)rss - (int64_t)m->rss);
46 m->rss = rss;
47 }
48}
49
50void mesh_meter_end(mesh_meter *m) {
51 mesh_slot_use *u = &mesh_cpuuse_slots[m->slot];
52 uint64_t now = mesh_thread_cpu_ns();
53 mesh_slot_use_add_cpu(u, now > m->cpu ? now - m->cpu : 0);
54 mesh_slot_use_add_rss(u, -(int64_t)m->rss);
55 atomic_fetch_sub_explicit(&u->units, 1, memory_order_relaxed);
56}