From 8cf114cbb4e58da06e987b205bdf55a91290f7c8 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sun, 23 Mar 2025 04:46:16 -0500 Subject: [PATCH] io actor --- scripts/core/io.js | 15 +++++++++++++++ source/jsffi.c | 2 +- source/prosperon.c | 43 ++++++++++++++++++++++++------------------- source/prosperon.h | 2 +- 4 files changed, 41 insertions(+), 21 deletions(-) create mode 100644 scripts/core/io.js diff --git a/scripts/core/io.js b/scripts/core/io.js new file mode 100644 index 00000000..9530a6f0 --- /dev/null +++ b/scripts/core/io.js @@ -0,0 +1,15 @@ +$_.unneeded(_ => { +}, Infinity) + +var subscribers = [] + +$_.receiver(e => { + if (e.type === "subscribe") { + if (!e.actor) throw Error('Got a subscribe message with no actor.'); + subscribers.push(e.actor) + return + } + + for (var a of subscribers) + $_.send(a, e) +}); diff --git a/source/jsffi.c b/source/jsffi.c index d56e06d7..c4b8a73d 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -6784,7 +6784,7 @@ JSC_CCALL(os_unneeded, } actor->unneeded = JS_DupValue(js, argv[0]); - actor->unneeded_secs = js2number(js, argv[1]); + JS_ToFloat64(js, &actor->unneeded_secs, argv[1]); END: if (actor->ar) { diff --git a/source/prosperon.c b/source/prosperon.c index 996e922d..41937a90 100644 --- a/source/prosperon.c +++ b/source/prosperon.c @@ -49,6 +49,8 @@ static struct { char *key; prosperon_rt *value; } *actors = NULL; static unsigned char *zip_buffer_global = NULL; static char *prosperon = NULL; +static prosperon_rt *io_actor = NULL; + static Uint32 queue_event; static SDL_AtomicInt shutdown; @@ -197,7 +199,7 @@ int prosperon_mount_core(void) return ret; } -void create_actor(int argc, char **argv) +prosperon_rt *create_actor(int argc, char **argv) { prosperon_rt *actor = calloc(sizeof(*actor), 1); actor->cmd.argc = argc; @@ -220,6 +222,8 @@ void create_actor(int argc, char **argv) SDL_UnlockMutex(actor->mutex); set_actor_state(actor); + + return actor; } prosperon_rt *get_actor(char *id) @@ -310,8 +314,10 @@ void set_actor_state(prosperon_rt *actor) if (actor->state == ACTOR_IDLE && !actor->ar && !has_upcoming) { if (JS_IsUndefined(actor->unneeded)) actor->ar = SDL_AddTimerNS(SDL_SECONDS_TO_NS(1), actor_remove_cb, actor); - else - actor->ar = SDL_AddTimerNS(SDL_SECONDS_TO_NS(actor->unneeded_secs), actor_remove_cb, actor); + else { + if (!isinf(actor->unneeded_secs)) + actor->ar = SDL_AddTimerNS(SDL_SECONDS_TO_NS(actor->unneeded_secs), actor_remove_cb, actor); + } } SDL_UnlockMutex(actor->msg_mutex); } @@ -321,6 +327,8 @@ void actor_turn(prosperon_rt *actor, int greedy) SDL_LockMutex(actor->msg_mutex); actor->state = ACTOR_RUNNING; SDL_UnlockMutex(actor->msg_mutex); + + TracyCFiberEnter(actor->id); int msgs = 0; int events = 0; @@ -405,10 +413,12 @@ void actor_turn(prosperon_rt *actor, int greedy) goto EVENT; END: + TracyCFiberLeave(actor->id); set_actor_state(actor); return; KILL: + TracyCFiberLeave(actor->id); actor_free(actor); } @@ -478,7 +488,7 @@ void actor_free(prosperon_rt *actor) free(actor); - if (remaining == 0) + if (remaining == 1) exit(0); } @@ -1347,9 +1357,17 @@ int main(int argc, char **argv) for (int i = 0; i < argc; i++) margv[i] = strdup(argv[i]); create_actor(argc, margv); + const char *io_script = "scripts/core/io.js"; + char **io_argv = malloc(sizeof(char*)*2); + io_argv[0] = strdup(argv[0]); + io_argv[1] = strdup(io_script); + io_actor = create_actor(2, io_argv); + /* Start the thread that pumps ready actors, one per logical core. */ for (int i = 0; i < cores; i++) { - SDL_Thread *thread = SDL_CreateThread(crank_actor, "actor_runner", NULL); + char threadname[128]; + snprintf(threadname, 128, "actor runner %d", i); + SDL_Thread *thread = SDL_CreateThread(crank_actor, threadname, NULL); arrput(runners,thread); } @@ -1366,20 +1384,7 @@ int main(int argc, char **argv) goto QUEUE; WotaBuffer wb = event2wota(&event); - - // Broadcast this event to all actors - SDL_LockMutex(actors_mutex); - for (int i = 0; i < shlen(actors); i++) { - // Make a fresh copy so each actor owns and frees it independently - size_t total_bytes = wb.size * sizeof(uint64_t); - void *msg = malloc(total_bytes); - memcpy(msg, wb.data, total_bytes); - - send_message(actors[i].key, msg); - } - SDL_UnlockMutex(actors_mutex); - - wota_buffer_free(&wb); // free WotaBuffer + send_message(io_actor->id, wb.data); QUEUE: SDL_LockMutex(queue_mutex); diff --git a/source/prosperon.h b/source/prosperon.h index 1b53ea8e..e8e0d868 100644 --- a/source/prosperon.h +++ b/source/prosperon.h @@ -68,7 +68,7 @@ typedef struct prosperon_rt { extern SDL_ThreadID main_thread; extern SDL_TLSID prosperon_id; -void create_actor(int argc, char **argv); +prosperon_rt *create_actor(int argc, char **argv); char *register_actor(char *id, prosperon_rt *actor); void actor_free(prosperon_rt *actor); char *send_message(char *id, void *msg);