==> 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}