io actor
Some checks failed
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled

This commit is contained in:
2025-03-23 04:46:16 -05:00
parent f9100da8a2
commit 8cf114cbb4
4 changed files with 41 additions and 21 deletions

15
scripts/core/io.js Normal file
View File

@@ -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)
});

View File

@@ -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) {

View File

@@ -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,9 +314,11 @@ 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
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);
}
@@ -322,6 +328,8 @@ void actor_turn(prosperon_rt *actor, int greedy)
actor->state = ACTOR_RUNNING;
SDL_UnlockMutex(actor->msg_mutex);
TracyCFiberEnter(actor->id);
int msgs = 0;
int events = 0;
int need_stop = 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);

View File

@@ -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);