==> src/rate.c <==1/* jobs.rs's Rate and lease_time. */
2#include "mesh/jobs/rate.h"
3
4void mj_rate_count(mj_rate *r, uint64_t n, uint64_t now) {
5 if (r->t0 == 0) r->t0 = now;
6 r->k += n;
7 uint64_t dt = now > r->t0 ? now - r->t0 : 0;
8 if (dt >= 400) {
9 double inst = (double)r->k * 1000.0 / (double)dt;
10 r->ips = r->ips == 0.0 ? inst : 0.5 * r->ips + 0.5 * inst;
11 r->t0 = now;
12 r->k = 0;
13 }
14}
15
16void mj_rate_busy(mj_rate *r, uint64_t now) {
17 if (r->idle_at > 0 && (now > r->idle_at ? now - r->idle_at : 0) > MESH_JOBS_IDLE_MS) {
18 r->t0 = now;
19 r->k = 0;
20 }
21 r->idle_at = 0;
22}
23
24void mj_rate_lease_done(mj_rate *r, uint64_t n, uint64_t issued, uint64_t now, bool last) {
25 if (r->ips == 0.0 && now > issued) r->ips = (double)n * 1000.0 / (double)(now - issued);
26 /* Slow start: a lease done in under half LEASE_MS (end to end) doubles the next (if it was of the
27 * full size: a lease cut short by the job's tail says nothing); one over 3 x LEASE_MS halves it. */
28 uint64_t t = now > issued ? now - issued : 0;
29 if (t * 2 < MESH_JOBS_LEASE_MS && n * 2 >= r->target) {
30 uint64_t m = r->target > n ? r->target : n;
31 r->target = m * 2 < MESH_JOBS_LEASE_MAX ? m * 2 : MESH_JOBS_LEASE_MAX;
32 } else if (t > 3 * MESH_JOBS_LEASE_MS) r->target = n / 2 > 1 ? n / 2 : 1;
33 if (last) r->idle_at = now > 1 ? now : 1;
34}
35
36uint64_t mj_lease_time(uint64_t n, double rate) {
37 if (rate > 0.0) {
38 double t = (double)n * 1000.0 / rate;
39 /* Rust's `as u64` saturates (and a NaN is 0). */
40 uint64_t ms = t != t ? 0 : t >= 18446744073709551615.0 ? UINT64_MAX : (uint64_t)t;
41 return ms + 1;
42 }
43 return 10000;
44}