diff --git a/README.md b/README.md
index 31acba2..0829e7c 100644
--- a/README.md
+++ b/README.md
@@ -297,7 +297,7 @@ sai-device|Helper that coordinates which builds wants and can use specific embed
sai-expect|Helper run by embedded build flow to capture serial traffic and react to keywords
sai-jig|Helper for embedded devices that lets another device control its buttons, reset etc as part of the embedded build flow
-First you must build lws with appropriate options.
+First you must build main branch lws with appropriate options.
For redhat type distros, you probably need to add /usr/local/lib to the
/etc/ld.so.conf before ldconfig can rgister the new libwebsockets.so
@@ -305,20 +305,22 @@ For redhat type distros, you probably need to add /usr/local/lib to the
```
$ git clone https://libwebsockets.org/repo/libwebsockets
$ cd libwebsockets && mkdir build && cd build && \
- cmake .. -DLWS_UNIX_SOCK=1 -DLWS_WITH_STRUCT_JSON=1 -DLWS_WITH_JOSE=1 \
- -DLWS_WITH_STRUCT_SQLITE3=1 -DLWS_WITH_GENCRYPTO=1 -DLWS_WITH_SPAWN=1 \
- -DLWS_WITH_SECURE_STREAMS=1 -DLWS_WITH_THREADPOOL=1
+ cmake .. -DLWS_LOGS_TIMESTAMP=0 -DLWS_WITH_STRUCT_JSON=1 -DLWS_WITH_JOSE=1 \
+ -DLWS_WITH_STRUCT_SQLITE3=1 -DLWS_WITH_GENCRYPTO=1 -DLWS_WITH_SPAWN=1
$ make -j && sudo make -j install && sudo ldconfig
```
The actual cmake options needed depends on if you are building sai-server and / or
sai-builder.
-Feature|lws options
+lws cmake option|Meaning
---|---
-either|`-DLWS_WITH_STRUCT_JSON=1` `-DLWS_WITH_SECURE_STREAMS=1`
-server|`-DLWS_UNIX_SOCK=1` `-DLWS_WITH_GENCRYPTO=1` `-DLWS_WITH_STRUCT_SQLITE3=1` `-DLWS_WITH_JOSE=1`
-builder + related|`-DLWS_WITH_SPAWN=1` `-DLWS_WITH_THREADPOOL=1`
+`-DLWS_LOGS_TIMESTAMP=0` | Avoids duplicating log timestamp in syslog
+`-DLWS_WITH_STRUCT_JSON=1` | Support for struct -> JSON -> struct
+`-DLWS_WITH_STRUCT_SQLITE3=1` | Support for struct -> sqlite3 -> struct
+`-DLWS_WITH_SPAWN=1` | Support for crossplatform process spawning
+`-DLWS_WITH_GENCRYPTO=1` | Supoort for cross-tls library crypto
+`-DLWS_WITH_JOSE=1` | Support for JOSE web tokens
You can also define `-DLWS_WITH_SYS_METRICS=1` on lws to enable build of
openmetrics pieces in sai when built against lws.
diff --git a/assets/sai.js b/assets/sai.js
index 8bc7959..0bc7372 100644
--- a/assets/sai.js
+++ b/assets/sai.js
@@ -1006,16 +1006,12 @@ function createBuilderDiv(plat) {
innerHTML += `<img class="ip1 tread1" src="/sai/arch-${plat_arch}.svg" onerror="this.src='/sai/generic.svg';this.onerror=null;">`;
innerHTML += `<img class="ip1 tread2" src="/sai/tc-${plat_tc}.svg" onerror="this.src='/sai/generic.svg';this.onerror=null;">`;
innerHTML += `<br>${plat.peer_ip}`;
- innerHTML += `<div class="instload" id="instload-${plat.name}">`;
-
- // Create initial idle squares
- for (let i = 0; i < plat.instances; i++) {
- innerHTML += `<div class="inst_box inst_idle" title="instance ${i}: idle">` +
- `<div class="inst_bar"></div>` +
- `</div>`;
- }
-
- innerHTML += `</div></td></tr></tbody></table>`;
+ innerHTML += `<div class="instload" id="instload-${plat.name}">` +
+ `<div class="inst_box inst_idle" title="active steps: 0">` +
+ `<div class="inst_text">0</div>` +
+ `<div class="inst_bar"></div>` +
+ `</div>` +
+ `</div></td></tr></tbody></table>`;
platDiv.innerHTML = innerHTML;
@@ -1601,74 +1597,41 @@ function ws_open_sai()
break;
case "com.warmcat.sai.loadreport":
- if (!jso.platforms || !Array.isArray(jso.platforms)) {
+ const loadContainer = document.getElementById("instload-" + jso.builder_name);
+ if (!loadContainer) {
break;
}
- for (const platformReport of jso.platforms) {
- const platformName = platformReport.platform_name;
- if (!platformName) {
- continue;
- }
-
- const loadContainer = document.getElementById("instload-" + platformName);
- if (!loadContainer) {
- continue;
- }
-
- if (platformReport.loads && Array.isArray(platformReport.loads)) {
- const instanceDivs = loadContainer.getElementsByClassName("inst_box");
-
- for (let i = 0; i < platformReport.loads.length; i++) {
- const instanceLoad = platformReport.loads[i];
- const instanceDiv = instanceDivs[i];
+ const instanceDiv = loadContainer.querySelector(".inst_box");
+ if (!instanceDiv) {
+ break;
+ }
- if (!instanceDiv) {
- break;
- }
+ const textDiv = instanceDiv.querySelector(".inst_text");
+ const barDiv = instanceDiv.querySelector(".inst_bar");
- let cpu = instanceLoad.cpu_percent / 10.0;
- let stateText = instanceLoad.state ? 'busy' : 'idle';
- instanceDiv.title = `Instance ${i}: ${stateText}\nCPU: ${cpu.toFixed(1)}%`;
+ if (textDiv) {
+ textDiv.textContent = jso.active_steps;
+ }
- if (instanceLoad.state) {
- instanceDiv.classList.add("inst_busy");
- instanceDiv.classList.remove("inst_idle");
- } else {
- instanceDiv.classList.add("inst_idle");
- instanceDiv.classList.remove("inst_busy");
- }
+ instanceDiv.title = `Active steps: ${jso.active_steps}\n` +
+ `CPU: ${(jso.cpu_percent / 10).toFixed(1)}%\n` +
+ `Free RAM: ${humanize(jso.free_ram_kib * 1024)}B\n` +
+ `Free Disk: ${humanize(jso.free_disk_kib * 1024)}B`;
+
+ if (jso.active_steps > 0) {
+ instanceDiv.classList.add("inst_busy");
+ instanceDiv.classList.remove("inst_idle");
+ } else {
+ instanceDiv.classList.add("inst_idle");
+ instanceDiv.classList.remove("inst_busy");
+ }
- // The bar is always the first (and only) child of the inst_box div.
- const bar = instanceDiv.firstChild;
- if (bar && bar.classList.contains("inst_bar")) {
- // cpu_percent is in tenths of a percent, relative to ONE core.
- // So 1000 = 100% = 1 full core.
- let total_cpu_capacity = jso.core_count * 1000;
-
- // Normalize the load to be a percentage of the ENTIRE system's capacity
- let cpu_percentage = (instanceLoad.cpu_percent / total_cpu_capacity) * 100;
-
- if (cpu_percentage > 100) cpu_percentage = 100;
- if (cpu_percentage < 0) cpu_percentage = 0;
- if (cpu_percentage > 0 && cpu_percentage < 1) cpu_percentage = 1;
-
- bar.style.height = `${cpu_percentage}%`;
-
- // Update the class for idle/busy state
- if (instanceLoad.state) { // state == 1 means busy
- instanceDiv.classList.add("inst_busy");
- instanceDiv.classList.remove("inst_idle");
- } else { // state == 0 means idle
- instanceDiv.classList.add("inst_idle");
- instanceDiv.classList.remove("inst_busy");
- }
- } else {
- // This console log will tell us if the bar element is missing
- console.error("Could not find .inst_bar child in .inst_box for", instanceDiv);
- }
- }
- }
+ if (barDiv) {
+ let cpu_percentage = (jso.cpu_percent / (jso.core_count * 1000)) * 100;
+ if (cpu_percentage > 100) cpu_percentage = 100;
+ if (cpu_percentage < 0) cpu_percentage = 0;
+ barDiv.style.height = `${cpu_percentage}%`;
}
break;
diff --git a/src/builder/b-comms.c b/src/builder/b-comms.c
index 8f955e4..7b21996 100644
--- a/src/builder/b-comms.c
+++ b/src/builder/b-comms.c
@@ -170,11 +170,6 @@ saib_m_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf, size_t *len,
n = (int)w;
lws_dll2_remove(&lr->list);
- lws_start_foreach_dll_safe(struct lws_dll2 *, il, il1, lr->platforms.head) {
- sai_platform_load_t *i = lws_container_of(il, sai_platform_load_t, list);
- lws_dll2_remove(&i->list);
- free(i);
- } lws_end_foreach_dll_safe(il, il1);
free(lr);
r = lws_ss_request_tx(spm->ss);
@@ -484,52 +479,21 @@ saib_sul_load_report_cb(struct lws_sorted_usec_list *sul)
lr->core_count = saib_get_cpu_count();
lr->free_ram_kib = saib_get_free_ram_kib();
lr->free_disk_kib = saib_get_free_disk_kib(builder.home);
-
- int system_load = saib_get_system_cpu(&builder);
-
- /*
- * Iterate all platforms. For each platform, create a sai_platform_load_t
- * and populate its list of instance loads.
- */
+ lr->cpu_percent = (unsigned int)saib_get_system_cpu(&builder);
+ lr->active_steps = 0;
lws_start_foreach_dll(struct lws_dll2 *, p, builder.sai_plat_owner.head) {
sp = lws_container_of(p, sai_plat_t, sai_plat_list);
-
- sai_platform_load_t *pl = calloc(1, sizeof(*pl));
- if (!pl)
- continue;
-
- lws_strncpy(pl->platform_name, sp->name, sizeof(pl->platform_name));
-
lws_start_foreach_dll(struct lws_dll2 *, d, sp->nspawn_owner.head) {
- struct sai_nspawn *ns = lws_container_of(d, struct sai_nspawn, list);
- sai_instance_load_t *il = calloc(1, sizeof(*il));
- int load = -1;
-
- if (il) {
- il->state = (ns->state == NSSTATE_EXECUTING_STEPS);
-
- if (!il->state) {
- /* If the instance is idle, its load is 0, regardless of system load. */
- load = 0;
- } else {
- somebody_not_idle = 1;
- /* The instance is busy, try to get a specific load for it. */
- load = saib_get_cgroup_cpu(ns);
- if (load < 0)
- /* Fall back to system load for busy instances on non-cgroup platforms. */
- load = system_load;
- }
-
- if (load < 0) /* Final fallback for errors */
- load = 10; /* Default to 1% if system load failed */
-
- il->cpu_percent = (uint16_t)load;
- lws_dll2_add_tail(&il->list, &pl->loads);
+ struct sai_nspawn *ns = lws_container_of(d,
+ struct sai_nspawn, list);
+ if (ns->state == NSSTATE_EXECUTING_STEPS) {
+ lr->active_steps++;
+ somebody_not_idle = 1;
}
} lws_end_foreach_dll(d);
- lws_dll2_add_tail(&pl->list, &lr->platforms);
+// lws_dll2_add_tail(&pl->list, &lr->platforms);
} lws_end_foreach_dll(p);
lws_dll2_add_tail(&lr->list, &spm->load_report_owner);
@@ -542,7 +506,6 @@ saib_sul_load_report_cb(struct lws_sorted_usec_list *sul)
saib_sul_load_report_cb, SAI_LOAD_REPORT_US);
}
-
static lws_ss_state_return_t
saib_m_state(void *userobj, void *sh, lws_ss_constate_t state,
lws_ss_tx_ordinal_t ack)
diff --git a/src/builder/b-conf.c b/src/builder/b-conf.c
index 3d9bda7..a35e256 100644
--- a/src/builder/b-conf.c
+++ b/src/builder/b-conf.c
@@ -68,7 +68,6 @@ enum enum_paths_global {
static const char * const paths[] = {
"platforms[].name",
- "platforms[].instances",
"platforms[].env[].*",
"platforms[].env[]",
"platforms[].servers",
@@ -78,7 +77,6 @@ static const char * const paths[] = {
enum enum_paths {
LEJPM_PLATFORMS_NAME,
- LEJPM_PLATFORMS_INSTANCES,
LEJPM_PLATFORMS_ENV_ITEM,
LEJPM_PLATFORMS_ENV,
LEJPM_PLATFORMS_SERVERS,
@@ -113,8 +111,6 @@ saib_conf_cb(struct lejp_ctx *ctx, char reason)
if (!a->sai_plat)
return -1;
- a->sai_plat->instances = 1; /* default */
-
lws_strncpy(a->sai_plat->sai_hash, BUILD_INFO,
sizeof(a->sai_plat->sai_hash));
lws_strncpy(a->sai_plat->lws_hash, LWS_BUILD_HASH,
@@ -136,38 +132,6 @@ saib_conf_cb(struct lejp_ctx *ctx, char reason)
if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match)
return 0;
- if (reason == LEJPCB_VAL_NUM_INT) {
- n = atoi(ctx->buf);
- switch (ctx->path_match - 1) {
-
- case LEJPM_PLATFORMS_INSTANCES:
- lwsl_notice("%s: instances %d\n", __func__, n);
- a->sai_plat->instances = n;
- /*
- * Instantiate n nspawns bound to this platform
- */
-
- for (n = 0; n < a->sai_plat->instances; n++) {
- struct sai_nspawn *ns = malloc(sizeof(*ns));
- if (!ns)
- return -1;
-
- memset(ns, 0, sizeof(*ns));
- ns->instance_idx = n;
- ns->builder = &builder;
- ns->sp = a->sai_plat;
- ns->task = NULL;
- lws_dll2_add_head(&ns->list,
- &a->sai_plat->nspawn_owner);
- }
- break;
-
- default:
- break;
- }
-
- return 0;
- }
if (reason != LEJPCB_VAL_STR_END)
return 0;
diff --git a/src/builder/b-metrics.c b/src/builder/b-metrics.c
index b577f73..170fcdc 100644
--- a/src/builder/b-metrics.c
+++ b/src/builder/b-metrics.c
@@ -25,6 +25,8 @@
#if defined(__linux__)
#include <sys/statvfs.h>
#elif defined(__APPLE__)
+#include <sys/mount.h>
+#include <sys/param.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
#include <mach/vm_statistics.h>
@@ -50,23 +52,17 @@ saib_get_free_ram_kib(void)
fclose(f);
return free_kib;
#elif defined(__APPLE__)
- int mib[2];
- size_t len;
- uint64_t total_mem;
- vm_size_t page_size;
- mach_msg_type_number_t count;
+ mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
vm_statistics64_data_t vm_stats;
+ vm_size_t page_size;
- mib[0] = CTL_HW;
- mib[1] = HW_MEMSIZE;
- len = sizeof(total_mem);
- sysctl(mib, 2, &total_mem, &len, NULL, 0);
-
- count = HOST_VM_INFO64_COUNT;
- if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&vm_stats, &count) != KERN_SUCCESS)
+ if (host_statistics64(mach_host_self(), HOST_VM_INFO64,
+ (host_info64_t)&vm_stats, &count) != KERN_SUCCESS)
return 0;
- return (unsigned int)((uint64_t)vm_stats.free_count * vm_stats.pagesize / 1024);
+ host_page_size(mach_host_self(), &page_size);
+
+ return (unsigned int)((uint64_t)vm_stats.free_count * page_size / 1024);
#elif defined(_WIN32)
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
@@ -80,13 +76,20 @@ saib_get_free_ram_kib(void)
unsigned int
saib_get_free_disk_kib(const char *path)
{
-#if defined(__linux__) || defined(__APPLE__)
+#if defined(__linux__)
struct statvfs s;
if (statvfs(path, &s))
return 0;
return (unsigned int)((uint64_t)s.f_bavail * s.f_frsize / 1024);
+#elif defined(__APPLE__)
+ struct statfs s;
+
+ if (statfs(path, &s))
+ return 0;
+
+ return (unsigned int)((uint64_t)s.f_bavail * (uint64_t)s.f_bsize / 1024);
#elif defined(_WIN32)
ULARGE_INTEGER free_bytes;
diff --git a/src/builder/b-nspawn.c b/src/builder/b-nspawn.c
index a53ce35..1c3a022 100644
--- a/src/builder/b-nspawn.c
+++ b/src/builder/b-nspawn.c
@@ -157,10 +157,7 @@ sai_lsp_reap_cb(void *opaque, const lws_spawn_resource_us_t *res, siginfo_t *si,
{
struct saib_opaque_spawn *op = (struct saib_opaque_spawn *)opaque;
struct sai_nspawn *ns = op ? op->ns : NULL;
-
- // lwsl_warn("%s: reap at %llu: we_killed_him: %d\n", __func__,
- // (unsigned long long)lws_now_usecs(), we_killed_him);
-
+ uint64_t us_wallclock = op ? (uint64_t)(lws_now_usecs() - op->start_time) : 0;
int exit_code = -1;
char s[256];
int n;
@@ -218,29 +215,36 @@ sai_lsp_reap_cb(void *opaque, const lws_spawn_resource_us_t *res, siginfo_t *si,
lws_dir(ns->inp, &du, lws_dir_du_cb);
{
- char h1[40], h2[40], h3[40], h4[40], h5[40], h6[40], h7[40], h8[40];
+ char h1[40], h2[40], h3[40], h4[40], h5[40], h6[40], h7[40], h8[40], h9[40], h10[40];
ns->us_cpu_user += res->us_cpu_user;
ns->us_cpu_sys += res->us_cpu_sys;
+ ns->us_wallclock += us_wallclock;
if (du.size_in_bytes > ns->worst_stg)
ns->worst_stg = du.size_in_bytes;
if (res->peak_mem_rss > ns->worst_mem)
ns->worst_mem = res->peak_mem_rss;
- lws_humanize(h1, sizeof(h1), ns->us_cpu_user, humanize_schema_us);
- lws_humanize(h2, sizeof(h2), ns->us_cpu_sys, humanize_schema_us);
- lws_humanize(h3, sizeof(h3), ns->worst_mem, humanize_schema_si);
- lws_humanize(h4, sizeof(h4), ns->worst_stg, humanize_schema_si);
- lws_humanize(h5, sizeof(h5), res->us_cpu_user, humanize_schema_us);
- lws_humanize(h6, sizeof(h6), res->us_cpu_sys, humanize_schema_us);
- lws_humanize(h7, sizeof(h7), res->peak_mem_rss, humanize_schema_si);
- lws_humanize(h8, sizeof(h8), du.size_in_bytes, humanize_schema_si);
+ lws_humanize_pad(h1, sizeof(h1), ns->us_cpu_user, humanize_schema_us);
+ lws_humanize_pad(h2, sizeof(h2), ns->us_cpu_sys, humanize_schema_us);
+ lws_humanize_pad(h3, sizeof(h3), ns->worst_mem, humanize_schema_si);
+ lws_humanize_pad(h4, sizeof(h4), ns->worst_stg, humanize_schema_si);
+ lws_humanize_pad(h5, sizeof(h5), res->us_cpu_user, humanize_schema_us);
+ lws_humanize_pad(h6, sizeof(h6), res->us_cpu_sys, humanize_schema_us);
+ lws_humanize_pad(h7, sizeof(h7), res->peak_mem_rss, humanize_schema_si);
+ lws_humanize_pad(h8, sizeof(h8), du.size_in_bytes, humanize_schema_si);
+ lws_humanize_pad(h9, sizeof(h9), us_wallclock, humanize_schema_us);
+ lws_humanize_pad(h10, sizeof(h10), ns->us_wallclock, humanize_schema_us);
+
+ n = lws_snprintf(s, sizeof(s),
+ ">saib> Step %d: [ %s (%s u / %s s), Mem: %sB, Stg: %sB ]\n",
+ ns->current_step + 1, h9, h5, h6, h7, h8);
+ saib_log_chunk_create(ns, s, (size_t)n, 3);
n = lws_snprintf(s, sizeof(s),
- ">saib> Step %d: Total [ %s u / %s s, Mem: %sB, Stg: %sB ], Step [ %s u / %s s, Mem: %sB, Stg: %sB ]\n",
- ns->current_step + 1, h1, h2, h3, h4, h5, h6, h7, h8);
-
+ ">saib> Task: [ %s (%s u / %s s), Mem: %sB, Stg: %sB ]\n",
+ h10, h1, h2, h3, h4);
saib_log_chunk_create(ns, s, (size_t)n, 3);
}
@@ -274,7 +278,7 @@ sai_lsp_reap_cb(void *opaque, const lws_spawn_resource_us_t *res, siginfo_t *si,
lws_strncpy(m->ref, ns->ref, sizeof(m->ref));
m->us_cpu_user = res->us_cpu_user;
m->us_cpu_sys = res->us_cpu_sys;
- m->wallclock_us = (uint64_t)(lws_now_usecs() - op->start_time);
+ m->wallclock_us = us_wallclock;
m->peak_mem_rss = res->peak_mem_rss;
m->stg_bytes = du.size_in_bytes;
@@ -435,7 +439,7 @@ saib_spawn_script(struct sai_nspawn *ns)
{
struct lws_spawn_piped_info info;
struct saib_opaque_spawn *op;
- char args[290], st[2048], *p;
+ char st[2048];
const char *respath = "unk";
const char * cmd[] = {
"/bin/ps",
@@ -452,32 +456,28 @@ saib_spawn_script(struct sai_nspawn *ns)
char cgroup[128];
#endif
- lws_strncpy(st, ns->sp->name, sizeof(st));
- lws_filename_purify_inplace(st);
- p = st;
- while ((p = strchr(p, '/')))
- *p = '_';
-
#if defined(WIN32)
- lws_snprintf(args, sizeof(args), "%s\\sai-build-script-%s-%d.bat",
- builder.home, st, ns->instance_idx);
+ lws_snprintf(ns->script_path, sizeof(ns->script_path),
+ "%s\\sai-build-script-%s.bat",
+ builder.home, ns->task->uuid);
#else
- lws_snprintf(args, sizeof(args), "%s/sai-build-script-%s-%d.sh",
- builder.home, st, ns->instance_idx);
+ lws_snprintf(ns->script_path, sizeof(ns->script_path),
+ "%s/sai-build-script-%s.sh",
+ builder.home, ns->task->uuid);
#endif
char one_step[4096];
lws_strncpy(one_step, ns->task->script, sizeof(one_step));
#if defined(WIN32)
- if (_sopen_s(&fd, args, _O_CREAT | _O_TRUNC | _O_WRONLY,
+ if (_sopen_s(&fd, ns->script_path, _O_CREAT | _O_TRUNC | _O_WRONLY,
_SH_DENYNO, _S_IWRITE))
fd = -1;
#else
- fd = open(args, O_CREAT | O_TRUNC | O_WRONLY, 0755);
+ fd = open(ns->script_path, O_CREAT | O_TRUNC | O_WRONLY, 0755);
#endif
if (fd < 0) {
- lwsl_err("%s: unable to open %s for write\n", __func__, args);
+ lwsl_err("%s: unable to open %s for write\n", __func__, ns->script_path);
return 1;
}
@@ -521,13 +521,13 @@ saib_spawn_script(struct sai_nspawn *ns)
if (write(fd, st, (unsigned int)n) != n) {
close(fd);
- lwsl_err("%s: failed to write runscript to %s\n", __func__, args);
+ lwsl_err("%s: failed to write runscript to %s\n", __func__, ns->script_path);
return 1;
}
close(fd);
- cmd[0] = args;
+ cmd[0] = ns->script_path;
#if defined(__linux__)
lws_snprintf(cgroup, sizeof(cgroup), "inst-%u-%d", (unsigned int)getpid(), ns->instance_idx);
diff --git a/src/builder/b-private.h b/src/builder/b-private.h
index 7146d14..5de8992 100644
--- a/src/builder/b-private.h
+++ b/src/builder/b-private.h
@@ -208,7 +208,7 @@ rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde);
extern const struct lws_protocols protocol_logproxy, protocol_resproxy;
void *
-thread_suspend(void *d);
+saib_thread_suspend(void *d);
int
diff --git a/src/builder/b-sai.c b/src/builder/b-sai.c
index 9ca1b55..a2ef7bd 100644
--- a/src/builder/b-sai.c
+++ b/src/builder/b-sai.c
@@ -312,8 +312,8 @@ saib_power_stay_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
struct sai_plat *sp = lws_container_of(mp, struct sai_plat,
sai_plat_list);
- if (sp->ongoing) {
- lwsl_warn("%s: cancelling idle grace time as ongoing tasks\n", __func__);
+ if (sp->nspawn_owner.count) {
+ lwsl_warn("%s: cancelling idle grace time as ongoing task steps\n", __func__);
lws_sul_cancel(&builder.sul_idle);
return 0;
}
@@ -759,9 +759,11 @@ int main(int argc, const char **argv)
*/
while (n >= 0) {
+#if !defined(WIN32)
int status;
- uint8_t d;
pid_t p;
+#endif
+ uint8_t d;
n = read(0, &d, 1);
lwsl_notice("%s: suspend process read returned %d\n", __func__, (int)n);
diff --git a/src/builder/b-task.c b/src/builder/b-task.c
index 51ea66a..a4c4448 100644
--- a/src/builder/b-task.c
+++ b/src/builder/b-task.c
@@ -134,9 +134,6 @@ saib_queue_task_status_update(sai_plat_t *sp, struct sai_plat_server *spm,
lws_snprintf(rej->host_platform, sizeof(rej->host_platform), "%s",
sp->name);
- rej->limit = sp->instances;
- rej->ongoing = sp->ongoing;
-
lws_dll2_add_tail(&rej->list, &spm->rejection_list);
return lws_ss_request_tx(spm->ss) ? -1 : 0;
@@ -153,45 +150,35 @@ saib_task_destroy(struct sai_nspawn *ns)
* If able, builder should reintroduce himself to get
* another task
*/
+
if (ns->spm) {
ns->spm->phase = PHASE_START_ATTACH;
if (lws_ss_request_tx(ns->spm->ss))
return;
}
+ if (ns->list.owner && ns->list.owner->count == 1) {
+ int m = 0;
- if (ns->task && ns->task->told_ongoing) {
/*
- * Account that we're not doing this task any more
+ * Is it the case that none of the platforms have
+ * any ongoing jobs then? We don't any more.
+ *
+ * If nobody does, start the grace time for suspend.
*/
- // lwsl_notice("%s: ongoing %d -> %d\n", __func__,
- // ns->sp->ongoing, ns->sp->ongoing - 1);
- ns->sp->ongoing--;
-
- if (!ns->sp->ongoing) {
- int m = 0;
-
- /*
- * Is it the case that none of the platforms have
- * any ongoing jobs then? We don't any more.
- *
- * If nobody does, start the grace time for suspend.
- */
-
- lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
- builder.sai_plat_owner.head) {
- struct sai_plat *sp = lws_container_of(d,
- struct sai_plat, sai_plat_list);
- if (sp->ongoing)
- m++;
- } lws_end_foreach_dll_safe(d, d1);
+ lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
+ builder.sai_plat_owner.head) {
+ struct sai_plat *sp = lws_container_of(d,
+ struct sai_plat, sai_plat_list);
+ if (sp->nspawn_owner.count)
+ m++;
+ } lws_end_foreach_dll_safe(d, d1);
- if (!m)
- lws_sul_schedule(builder.context, 0,
- &builder.sul_idle, sul_idle_cb,
- SAI_IDLE_GRACE_US);
- }
+ if (!m)
+ lws_sul_schedule(builder.context, 0,
+ &builder.sul_idle, sul_idle_cb,
+ SAI_IDLE_GRACE_US);
/*
* Schedule informing all the servers we're connected to
@@ -205,6 +192,12 @@ saib_task_destroy(struct sai_nspawn *ns)
lwsac_free(&ns->task->ac_task_container);
ns->task = NULL;
}
+
+ if (ns->script_path[0])
+ unlink(ns->script_path);
+
+ lws_dll2_remove(&ns->list);
+ free(ns);
}
static void
@@ -540,19 +533,13 @@ saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len)
} lws_end_foreach_dll_safe(d, d1);
if (!ns) {
-
- /*
- * Full up... reject the task and update every
- * server's model of our task load status
- */
-
- lwsl_notice("%s: plat '%s': no idle nspawn (of %d), "
- "plat load %d / %d\n", __func__, sp->name,
- n, sp->ongoing, sp->instances);
- if (saib_queue_task_status_update(sp, spm, task->uuid))
+ ns = malloc(sizeof(*ns));
+ if (!ns)
return -1;
-
- return 0;
+ memset(ns, 0, sizeof(*ns));
+ ns->builder = &builder;
+ ns->sp = sp;
+ lws_dll2_add_tail(&ns->list, &sp->nspawn_owner);
}
// lwsl_hexdump_warn(task->build, strlen(task->build));
@@ -662,17 +649,6 @@ saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len)
goto bail;
}
- /*
- * If we successfully set the threadpool task up, then we
- * bump our idea of what is ongoing... completing or failing
- * after that needs to adjust sp->ongoing accordingly
- */
-
- lwsl_notice("%s: ongoing %d -> %d\n", __func__, sp->ongoing,
- sp->ongoing + 1);
- sp->ongoing++;
- ns->task->told_ongoing = 1;
-
/* we're busy, we're not in the mood for suspending */
lwsl_notice("%s: cancelling suspend grace time\n", __func__);
lws_sul_cancel(&ns->builder->sul_idle);
diff --git a/src/common/include/private.h b/src/common/include/private.h
index 6b017a1..4219c94 100644
--- a/src/common/include/private.h
+++ b/src/common/include/private.h
@@ -60,33 +60,15 @@ enum {
SAISPRF_SIGNALLED = 0x4000,
};
-/*
- * per-instance load data.
- * Sent from builder -> server -> web -> browser.
- */
-typedef struct sai_instance_load {
- lws_dll2_t list;
- unsigned int cpu_percent; /* CPU usage for this instance * 100 */
- unsigned int state; /* 0 = idle, 1 = running */
-} sai_instance_load_t;
-
-/*
- * load report struct, sent in its own schema.
- */
-typedef struct sai_platform_load {
- lws_dll2_t list; /* Not used, for schema mapping */
- char platform_name[128];
- lws_dll2_owner_t loads;
-} sai_platform_load_t;
-
/* The top-level load report message from a builder */
typedef struct sai_load_report {
lws_dll2_t list; /* For queuing on sai_plat_server */
char builder_name[64];
int core_count;
- lws_dll2_owner_t platforms; /* List of sai_platform_load_t */
unsigned int free_ram_kib;
unsigned int free_disk_kib;
+ unsigned int active_steps;
+ unsigned int cpu_percent;
} sai_load_report_t;
/*
@@ -98,6 +80,12 @@ typedef struct sai_viewer_state {
unsigned int viewers;
} sai_viewer_state_t;
+typedef struct sai_platform_load {
+ lws_dll2_t list; /* Not used, for schema mapping */
+ char platform_name[128];
+ lws_dll2_owner_t loads;
+} sai_platform_load_t;
+
struct sai_nspawn;
@@ -134,8 +122,6 @@ typedef struct {
int state;
int uid;
int build_step;
-
- char told_ongoing;
} sai_task_t;
typedef struct sai_plat sai_plat_t;
@@ -156,6 +142,7 @@ struct sai_nspawn {
char inp[512];
char path[384];
+ char script_path[290];
char pending_mirror_log[128];
/* convenient place to store it */
@@ -182,8 +169,9 @@ struct sai_nspawn {
uint64_t last_cpu_usec;
lws_usec_t last_cpu_usec_time;
- uint64_t us_cpu_user;
- uint64_t us_cpu_sys;
+ uint64_t us_wallclock;
+ uint64_t us_cpu_user;
+ uint64_t us_cpu_sys;
uint64_t worst_mem;
uint64_t worst_stg;
@@ -221,8 +209,6 @@ typedef struct sai_rejection {
struct lws_dll2 list;
char host_platform[65];
char task_uuid[65];
- int ongoing;
- int limit;
} sai_rejection_t;
/*
@@ -443,9 +429,6 @@ typedef struct sai_plat {
int powering_up; /* 1 = sai-power is booting it */
int powering_down;
- int instances;
- int ongoing;
-
char windows;
int index; /* used to create unique build dir path */
@@ -530,7 +513,7 @@ extern const lws_struct_map_t
lsm_log[7],
lsm_artifact[8],
lsm_plat_list[1],
- lsm_task_rej[4],
+ lsm_task_rej[2],
lsm_task_cancel[1],
lsm_schema_json_map_can[1],
lsm_schema_json_map_task[1],
@@ -543,8 +526,8 @@ extern const lws_struct_map_t
lsm_schema_sq3_map_build_metric[1]
;
extern const lws_struct_map_t lsm_build_metric[9];
-extern const lws_struct_map_t lsm_plat[9];
-extern const lws_struct_map_t lsm_plat_for_json[13];
+extern const lws_struct_map_t lsm_plat[8];
+extern const lws_struct_map_t lsm_plat_for_json[11];
extern const lws_ss_info_t ssi_said_logproxy;
extern struct lws_ss_handle *ssh[3];
diff --git a/src/common/struct-metadata.c b/src/common/struct-metadata.c
index 7d62719..4453ddf 100644
--- a/src/common/struct-metadata.c
+++ b/src/common/struct-metadata.c
@@ -21,25 +21,15 @@
* lws_struct metadata for structs common to builder and server
*/
-const lws_struct_map_t lsm_instance_load[] = {
- LSM_UNSIGNED (sai_instance_load_t, cpu_percent, "cpu_percent"),
- LSM_UNSIGNED (sai_instance_load_t, state, "state"),
-};
-
-/* Map for a sai_platform_load_t object */
-const lws_struct_map_t lsm_platform_load[] = {
- LSM_CARRAY(sai_platform_load_t, platform_name, "platform_name"),
- LSM_LIST(sai_platform_load_t, loads, sai_instance_load_t, list,
- NULL, lsm_instance_load, "loads"),
-};
-
const lws_struct_map_t lsm_load_report_members[] = {
LSM_CARRAY (sai_load_report_t, builder_name, "builder_name"),
LSM_SIGNED (sai_load_report_t, core_count, "core_count"),
LSM_UNSIGNED (sai_load_report_t, free_ram_kib, "free_ram_kib"),
LSM_UNSIGNED (sai_load_report_t, free_disk_kib, "free_disk_kib"),
- LSM_LIST (sai_load_report_t, platforms, sai_platform_load_t, list,
- NULL, lsm_platform_load, "platforms"),
+ LSM_UNSIGNED (sai_load_report_t, active_steps, "active_steps"),
+ LSM_UNSIGNED (sai_load_report_t, cpu_percent, "cpu_percent"),
+// LSM_LIST (sai_load_report_t, platforms, sai_platform_load_t, list,
+// NULL, lsm_platform_load, "platforms"),
};
const lws_struct_map_t lsm_build_metric[] = {
@@ -78,7 +68,6 @@ const lws_struct_map_t lsm_schema_sq3_map_build_metric[] = {
const lws_struct_map_t lsm_plat[] = { /* !!! keep extern length in common/include/private.h in sync */
LSM_UNSIGNED (sai_plat_t, uid, "uid"),
LSM_STRING_PTR (sai_plat_t, name, "name"),
- LSM_UNSIGNED (sai_plat_t, instances, "instances"),
LSM_STRING_PTR (sai_plat_t, platform, "platform"),
LSM_UNSIGNED (sai_plat_t, last_seen, "last_seen"),
LSM_CARRAY (sai_plat_t, peer_ip, "peer_ip"),
@@ -91,8 +80,6 @@ const lws_struct_map_t lsm_plat[] = { /* !!! keep extern length in common/includ
const lws_struct_map_t lsm_plat_for_json[] = {
LSM_UNSIGNED(sai_plat_t, uid, "uid"),
LSM_STRING_PTR(sai_plat_t, name, "name"),
- LSM_SIGNED(sai_plat_t, ongoing, "ongoing"), // MUST be present
- LSM_SIGNED(sai_plat_t, instances, "instances"),
LSM_STRING_PTR(sai_plat_t, platform,"platform"),
LSM_SIGNED(sai_plat_t, online, "online"), // MUST be present
LSM_UNSIGNED(sai_plat_t, last_seen, "last_seen"),
@@ -192,8 +179,6 @@ const lws_struct_map_t lsm_schema_sq3_map_task[] = {
const lws_struct_map_t lsm_task_rej[] = {
LSM_CARRAY (sai_rejection_t, host_platform, "host_platform"),
LSM_CARRAY (sai_rejection_t, task_uuid, "task_uuid"),
- LSM_UNSIGNED (sai_rejection_t, ongoing, "ongoing"),
- LSM_UNSIGNED (sai_rejection_t, limit, "limit"),
};
const lws_struct_map_t lsm_schema_json_task_rej[] = {
diff --git a/src/server/s-central.c b/src/server/s-central.c
index 17808f6..9ccb5c6 100644
--- a/src/server/s-central.c
+++ b/src/server/s-central.c
@@ -160,11 +160,7 @@ sais_central_cb(lws_sorted_usec_list_t *sul)
vhd->server.builder_owner.head) {
sai_plat_t *cb = lws_container_of(p, sai_plat_t, sai_plat_list);
- lwsl_debug("%s: checking tasks %s %d %d %p\n", __func__,
- cb->name, cb->ongoing, cb->instances, cb->wsi);
-
- if (cb->wsi && lws_wsi_user(cb->wsi) &&
- cb->ongoing < cb->instances)
+ if (cb->wsi && lws_wsi_user(cb->wsi))
/*
* try to bind outstanding task to specific builder
* instance
diff --git a/src/server/s-task.c b/src/server/s-task.c
index 10934d9..21525d3 100644
--- a/src/server/s-task.c
+++ b/src/server/s-task.c
@@ -803,9 +803,6 @@ sais_allocate_task(struct vhd *vhd, struct pss *pss, sai_plat_t *cb,
const sai_task_t *task_template;
sai_task_t *task = NULL;
- if (cb->ongoing >= cb->instances)
- return 1;
-
/*
* Look for a task for this platform, on any event that needs building
*/
diff --git a/src/server/s-websrv.c b/src/server/s-websrv.c
index f4073a2..789898a 100644
--- a/src/server/s-websrv.c
+++ b/src/server/s-websrv.c
@@ -257,13 +257,10 @@ sais_list_builders(struct vhd *vhd)
if (live_builder) {
builder_from_db->online = 1;
- builder_from_db->ongoing = live_builder->ongoing;
lws_strncpy(builder_from_db->peer_ip, live_builder->peer_ip,
sizeof(builder_from_db->peer_ip));
- } else {
+ } else
builder_from_db->online = 0;
- builder_from_db->ongoing = 0;
- }
builder_from_db->powering_up = 0;
builder_from_db->powering_down = 0;
diff --git a/src/server/s-ws-builder.c b/src/server/s-ws-builder.c
index dc100f3..3094801 100644
--- a/src/server/s-ws-builder.c
+++ b/src/server/s-ws-builder.c
@@ -57,22 +57,21 @@ typedef struct sais_logcache_pertask {
} sais_logcache_pertask_t;
/* map for a single instance's load */
-static const lws_struct_map_t lsm_instance_load[] = {
- LSM_UNSIGNED(sai_instance_load_t, cpu_percent, "cpu_percent"),
- LSM_UNSIGNED(sai_instance_load_t, state, "state"),
-};
+//static const lws_struct_map_t lsm_instance_load[] = {
+// LSM_UNSIGNED(sai_instance_load_t, state, "state"),
+//};
-static const lws_struct_map_t lsm_platform_load[] = {
- LSM_CARRAY(sai_platform_load_t, platform_name, "platform_name"),
- LSM_LIST(sai_platform_load_t, loads, sai_instance_load_t, list,
- NULL, lsm_instance_load, "loads"),
-};
+// static const lws_struct_map_t lsm_platform_load[] = {
+// LSM_CARRAY(sai_platform_load_t, platform_name, "platform_name"),
+// LSM_LIST(sai_platform_load_t, loads, sai_instance_load_t, list,
+// NULL, lsm_instance_load, "loads"),
+//};
/* map for the members of the load report object */
static const lws_struct_map_t lsm_load_report_members[] = {
LSM_CARRAY(sai_load_report_t, builder_name, "builder_name"),
- LSM_LIST (sai_load_report_t, platforms, sai_platform_load_t, list,
- NULL, lsm_platform_load, "platforms"),
+// LSM_LIST (sai_load_report_t, platforms, sai_platform_load_t, list,
+// NULL, lsm_platform_load, "platforms"),
};
/*
@@ -281,7 +280,7 @@ sais_builder_from_uuid(struct vhd *vhd, const char *hostname, const char *_file,
sai_plat_list);
if (!strcmp(hostname, cb->name)) {
- lwsl_err("%s: %s:%d: found live builder %s\n", __func__, _file, _line, hostname);
+ lwsl_info("%s: %s:%d: found live builder %s\n", __func__, _file, _line, hostname);
cb->online = 1;
return cb;
}
@@ -501,6 +500,8 @@ sais_ws_json_rx_builder(struct vhd *vhd, struct pss *pss, uint8_t *buf, size_t b
memset(&pss->a, 0, sizeof(pss->a));
pss->a.map_st[0] = lsm_schema_map_ba;
pss->a.map_entries_st[0] = LWS_ARRAY_SIZE(lsm_schema_map_ba);
+ pss->a.map_st[1] = lsm_schema_map_ba;
+ pss->a.map_entries_st[1] = LWS_ARRAY_SIZE(lsm_schema_map_ba);
pss->a.ac_block_size = 4096;
lws_struct_json_init_parse(&pss->ctx, NULL, &pss->a);
@@ -572,7 +573,6 @@ handle:
/* Already exists (reconnect), just update dynamic info */
lwsl_err("%s: found live builder for %s\n", __func__, build->name);
live_cb->wsi = pss->wsi;
- live_cb->ongoing = 0; /* Reset ongoing task count on connect */
lws_strncpy(live_cb->peer_ip, pss->peer_ip, sizeof(live_cb->peer_ip));
lws_strncpy(live_cb->sai_hash, build->sai_hash,
sizeof(live_cb->sai_hash));
@@ -595,7 +595,6 @@ handle:
memcpy(p_str, build->name, nlen);
live_cb->platform = p_str + nlen;
memcpy(p_str + nlen, build->platform, plen);
- live_cb->instances = build->instances;
lws_strncpy(live_cb->sai_hash, build->sai_hash,
sizeof(live_cb->sai_hash));
lws_strncpy(live_cb->lws_hash, build->lws_hash,
@@ -720,13 +719,8 @@ bail:
break;
}
- /* update our info about builder state with reality */
-
- cb->ongoing = rej->ongoing;
- cb->instances = rej->limit;
-
- lwsl_notice("%s: builder %s reports occupancy %d/%d (rej %s)\n",
- __func__, cb->name, cb->ongoing, cb->instances,
+ lwsl_notice("%s: builder %s reports rejection (rej %s)\n",
+ __func__, cb->name,
rej->task_uuid[0] ? rej->task_uuid : "none");
if (rej->task_uuid[0])
@@ -736,6 +730,13 @@ bail:
break;
case SAIM_WSSCH_BUILDER_LOADREPORT:
+ {
+ sai_load_report_t *lr = (sai_load_report_t *)pss->a.dest;
+
+ lwsl_notice("%s: loadreport from %s: ram %uk, disk %uk\n",
+ __func__, lr->builder_name, lr->free_ram_kib,
+ lr->free_disk_kib);
+ }
// lwsl_wsi_user(pss->wsi, "SAIM_WSSCH_BUILDER_LOADREPORT broadcasting\n");
sais_websrv_broadcast(vhd->h_ss_websrv, (const char *)buf, bl);
break;
diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c
index 8767cb6..743d3ce 100644
--- a/src/web/w-ws-browser.c
+++ b/src/web/w-ws-browser.c
@@ -57,7 +57,7 @@ saiw_ws_broadcast_raw(struct vhd *vhd, const void *buf, size_t len, unsigned int
// lwsl_notice("%s: broadcast to %d / %d browsers\n", __func__, eff, (int)vhd->browsers.count);
}
-extern const lws_struct_map_t lsm_load_report_members[2];
+extern const lws_struct_map_t lsm_load_report_members[7];
/*
* For decoding specific event data request from browser