skip to content
==> 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}