==> src/sched_member.c <==1/* Member, Perf and the performance map (see the header). */
2#include "mesh/sched_member.h"
3#include "mesh/mt.h"
4
5#include <stdlib.h>
6#include <string.h>
7
8msm_member msm_member_default(void) { return (msm_member){0}; }
9
10void msm_set_str(char *dst, size_t cap, const char *s) {
11 size_t n = strlen(s);
12 if (n >= cap) n = cap - 1;
13 memcpy(dst, s, n);
14 dst[n] = 0;
15}
16
17msm_member msm_member_clone(const msm_member *m) {
18 msm_member c = *m;
19 c.busy = m->busy ? mt_strdup(m->busy) : NULL;
20 c.fails = (ms_map){0};
21 for (size_t i = 0; i < m->fails.n; i++) ms_set(&c.fails, m->fails.k[i], m->fails.v[i], true);
22 return c;
23}
24
25void msm_member_free(msm_member *m) {
26 free(m->busy);
27 m->busy = NULL;
28 ms_free(&m->fails);
29}
30
31size_t msm_executors(const msm_member *m, const char *out[3]) {
32 size_t n = 0;
33 out[n++] = m->gpu;
34 const char *cpu[2] = {"wasm", "native"};
35 for (int i = 0; i < 2; i++) {
36 bool have = false;
37 for (size_t j = 0; j < n; j++)
38 if (strcmp(out[j], cpu[i]) == 0) have = true;
39 if (!have) out[n++] = cpu[i];
40 }
41 return n;
42}
43
44const char *msm_exec_for(const msm_member *m, char *const *backends, size_t nb) {
45 const char *ex[3];
46 size_t n = msm_executors(m, ex);
47 for (size_t i = 0; i < nb; i++)
48 for (size_t j = 0; j < n; j++)
49 if (strcmp(backends[i], ex[j]) == 0) return backends[i];
50 return NULL;
51}
52
53mof32 msm_rtt_to(const msm_member *m, uint32_t k) {
54 if (k == m->id) return mof32_some(0.0f);
55 if (k >= m->nrtt) return mof32_none();
56 return m->rtt_us[k];
57}
58
59bool msm_perf_eq(const msm_perf *a, const msm_perf *b) {
60 return a->hash == b->hash && strcmp(a->exec, b->exec) == 0 && a->run == b->run && mof32_eq(a->task_us, b->task_us) && a->tasks_s == b->tasks_s &&
61 a->cpu == b->cpu && mof32_eq(a->share, b->share) && a->rss_mb == b->rss_mb;
62}
63
64static int key_cmp(const char *an, uint32_t am, const char *bn, uint32_t bm) {
65 int c = strcmp(an, bn);
66 if (c) return c;
67 return am < bm ? -1 : am > bm;
68}
69
70/* The index of (name, member), or where it goes. */
71static size_t find(const msm_perfs *p, const char *name, uint32_t member, bool *found) {
72 size_t lo = 0, hi = p->n;
73 while (lo < hi) {
74 size_t mid = (lo + hi) / 2;
75 int c = key_cmp(p->name[mid], p->member[mid], name, member);
76 if (c == 0) {
77 *found = true;
78 return mid;
79 }
80 if (c < 0) lo = mid + 1;
81 else hi = mid;
82 }
83 *found = false;
84 return lo;
85}
86
87const msm_perf *msm_perfs_get(const msm_perfs *p, const char *name, uint32_t member) {
88 bool f;
89 size_t i = find(p, name, member, &f);
90 return f ? &p->perf[i] : NULL;
91}
92
93void msm_perfs_set(msm_perfs *p, const char *name, uint32_t member, const msm_perf *perf) {
94 bool f;
95 size_t i = find(p, name, member, &f);
96 if (f) {
97 p->perf[i] = *perf;
98 return;
99 }
100 if (p->n == p->cap) {
101 p->cap = p->cap ? p->cap * 2 : 8;
102 p->name = mt_realloc(p->name, p->cap * sizeof *p->name);
103 p->member = mt_realloc(p->member, p->cap * sizeof *p->member);
104 p->perf = mt_realloc(p->perf, p->cap * sizeof *p->perf);
105 }
106 memmove(p->name + i + 1, p->name + i, (p->n - i) * sizeof *p->name);
107 memmove(p->member + i + 1, p->member + i, (p->n - i) * sizeof *p->member);
108 memmove(p->perf + i + 1, p->perf + i, (p->n - i) * sizeof *p->perf);
109 p->name[i] = mt_strdup(name);
110 p->member[i] = member;
111 p->perf[i] = *perf;
112 p->n++;
113}
114
115void msm_perfs_range(const msm_perfs *p, const char *name, size_t *lo, size_t *hi) {
116 bool f;
117 *lo = find(p, name, 0, &f);
118 size_t i = *lo;
119 while (i < p->n && strcmp(p->name[i], name) == 0) i++;
120 *hi = i;
121}
122
123void msm_perfs_remove_at(msm_perfs *p, size_t i) {
124 free(p->name[i]);
125 memmove(p->name + i, p->name + i + 1, (p->n - i - 1) * sizeof *p->name);
126 memmove(p->member + i, p->member + i + 1, (p->n - i - 1) * sizeof *p->member);
127 memmove(p->perf + i, p->perf + i + 1, (p->n - i - 1) * sizeof *p->perf);
128 p->n--;
129}
130
131msm_perfs msm_perfs_clone(const msm_perfs *p) {
132 msm_perfs c = {0};
133 for (size_t i = 0; i < p->n; i++) msm_perfs_set(&c, p->name[i], p->member[i], &p->perf[i]);
134 return c;
135}
136
137void msm_perfs_free(msm_perfs *p) {
138 for (size_t i = 0; i < p->n; i++) free(p->name[i]);
139 free(p->name);
140 free(p->member);
141 free(p->perf);
142 *p = (msm_perfs){0};
143}