==> src/peer_view.c <==1/* peer_sched.rs: ViewWait and view_take; LoadAvg. */
2#include "mesh/peer_view.h"
3#include "mesh/mt.h"
4
5#include <stdlib.h>
6#include <string.h>
7
8mpv_wait mpv_wait_new(uint32_t from, uint64_t deadline, size_t limit) { return (mpv_wait){.from = from, .deadline = deadline, .limit = limit}; }
9
10void mpv_wait_free(mpv_wait *w) {
11 free(w->buf);
12 rs_free(&w->have);
13 *w = (mpv_wait){0};
14}
15
16int mpv_take(mpv_wait *w, uint32_t total32, uint32_t off32, const uint8_t *b, size_t n, char **err) {
17 size_t total = total32, off = off32;
18 if (total > w->limit) {
19 *err = mt_fmt("F_VIEW of %zu bytes: the view is at most %zu bytes", total, w->limit);
20 return -1;
21 }
22 if (!w->has_total) {
23 w->has_total = true;
24 w->total = total;
25 w->buf = mt_alloc(total ? total : 1);
26 } else if (w->total != total) {
27 *err = mt_fmt("F_VIEW chunks disagree on the view's size (%zu, then %zu)", w->total, total);
28 return -1;
29 }
30 if (off + n < off || off + n > total) {
31 *err = mt_fmt("F_VIEW chunk %zu+%zu past %zu", off, n, total);
32 return -1;
33 }
34 if (n) memcpy(w->buf + off, b, n);
35 rs_insert(&w->have, off, off + n);
36 return rs_len(&w->have) == total ? 1 : 0;
37}
38
39void mpv_load_add(mpv_load *l, uint64_t at, float cpu, mof32 psi_cpu, mof32 psi_mem, mof32 share) {
40 if (at == l->at) return;
41 l->at = at;
42#define EASE(a, x) ((a) + MPV_LOAD_ALPHA * ((x) - (a)))
43#define OPT(a, x) ((a).some && (x).some ? mof32_some(EASE((a).v, (x).v)) : (x))
44 l->cpu = EASE(l->cpu, cpu);
45 l->psi_cpu = OPT(l->psi_cpu, psi_cpu);
46 l->psi_mem = OPT(l->psi_mem, psi_mem);
47 l->share = OPT(l->share, share);
48}