skip to content
==> src/load_share.c <==
1/* load.rs's GPU share arithmetic, in the Rust's float widths and order. */
2#include "mesh/load_share.h"
3
4
5mesh_nl mesh_nl_delta(const mesh_nl *now, const mesh_nl *prev) {
6    mesh_nl d = {0, 0, 0, 0};
7    if (now->obs < prev->obs || now->lost < prev->lost) return d;
8    d.obs = now->obs - prev->obs;
9    d.lost = now->lost - prev->lost;
10    d.gaps = now->gaps - prev->gaps;
11    d.queue_us = now->queue_us - prev->queue_us;
12    return d;
13}
14
15void mesh_nl_add(mesh_nl *s, const mesh_nl *d) {
16    s->obs += d->obs;
17    s->lost += d->lost < d->obs ? d->lost : d->obs;
18    s->gaps += d->gaps;
19    s->queue_us += d->queue_us;
20}
21
22mesh_share mesh_share_of(const mesh_nl *d) {
23    mesh_share s = {false, 0, 0, 0, 0};
24    if (d->obs == 0) return s;
25    uint64_t lost = d->lost < d->obs ? d->lost : d->obs;
26    double gaps = (double)d->gaps;
27    s.has_share = true;
28    s.share = (float)(1.0 - (double)lost / (double)d->obs);
29    if (d->gaps > 0) {
30        s.slice_us = (float)((double)(d->obs - lost) / gaps / 1e3);
31        s.gap_us = (float)((double)lost / gaps / 1e3);
32        s.queue_us = (float)((double)d->queue_us / gaps);
33    }
34    return s;
35}
36
37uint32_t mesh_quantile(const uint32_t *sorted, size_t n, double q) {
38    if (n == 0) return 0;
39    /* f64::round (half away from zero) of a non-negative x, without libm. */
40    double x = (double)(n - 1) * q;
41    size_t r = (size_t)x;
42    if (x - (double)r >= 0.5) r++;
43    return sorted[r];
44}