diff --git a/src/builder/b-private.h b/src/builder/b-private.h
index 5b1ac65..c9bcff4 100644
--- a/src/builder/b-private.h
+++ b/src/builder/b-private.h
@@ -159,6 +159,9 @@ struct sai_builder {
#endif
char stay;
+ char event_affinity[65];
+ char event_affinity_active;
+
/* resource management */
uint64_t ram_limit_kib;
diff --git a/src/builder/b-sai.c b/src/builder/b-sai.c
index e0daf92..4d656e5 100644
--- a/src/builder/b-sai.c
+++ b/src/builder/b-sai.c
@@ -528,6 +528,11 @@ saib_app_run(int argc, const char **argv)
if ((p = lws_cmdline_option(argc, argv, "-c")))
config_dir = p;
+ if (lws_cmdline_option(argc, argv, "-E")) {
+ builder.event_affinity_active = 1;
+ lwsl_notice("%s: event affinity mode enabled (ephemeral VM)\n", __func__);
+ }
+
#if defined(__NetBSD__) || defined(__OpenBSD__)
if (lws_cmdline_option(argc, argv, "-D")) {
if (lws_daemonize("/var/run/sai_builder.pid"))
diff --git a/src/builder/b-task.c b/src/builder/b-task.c
index 453698b..2c9c006 100644
--- a/src/builder/b-task.c
+++ b/src/builder/b-task.c
@@ -177,6 +177,19 @@ saib_can_accept_task(sai_task_t *task, sai_plat_t *sp)
unsigned int executing = 0;
+ if (builder.event_affinity_active) {
+ if (!builder.event_affinity[0]) {
+ lws_strncpy(builder.event_affinity, task->event_uuid,
+ sizeof(builder.event_affinity));
+ lwsl_notice("%s: locked affinity to event %s\n",
+ __func__, builder.event_affinity);
+ } else if (strcmp(builder.event_affinity, task->event_uuid)) {
+ lwsl_notice("%s: reject task %s: affinity locked to %s\n",
+ __func__, task->uuid, builder.event_affinity);
+ return 1;
+ }
+ }
+
if ((((builder.ram_limit_kib * 4) / 3) - builder.ram_reserved_kib) < task->est_peak_mem_kib) {
lwsl_notice("%s: reject task %s: not enough RAM: task %u vs %u lim - %u res\n", __func__,
task->uuid, (unsigned int)task->est_peak_mem_kib, (unsigned int)builder.ram_limit_kib, (unsigned int)builder.ram_reserved_kib);