scheduler starts
This commit is contained in:
@@ -298,6 +298,8 @@ int cell_init(int argc, char **argv)
|
||||
|
||||
if (!find_cell_shop()) return 1;
|
||||
|
||||
actor_initialize();
|
||||
|
||||
size_t boot_size;
|
||||
int boot_is_bin = 1;
|
||||
char *boot_data = load_core_file(BOOTSTRAP_MACH, &boot_size);
|
||||
@@ -310,26 +312,54 @@ int cell_init(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
if (!rt) {
|
||||
g_runtime = JS_NewRuntime();
|
||||
if (!g_runtime) {
|
||||
printf("Failed to create JS runtime\n");
|
||||
free(boot_data);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(rt, 16 * 1024 * 1024);
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(g_runtime, 16 * 1024 * 1024);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
free(boot_data); JS_FreeRuntime(rt);
|
||||
free(boot_data); JS_FreeRuntime(g_runtime);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create a cell_rt for the CLI context so JS-C bridge functions work */
|
||||
cell_rt *cli_rt = calloc(sizeof(*cli_rt), 1);
|
||||
cli_rt->mutex = malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutexattr_t mattr;
|
||||
pthread_mutexattr_init(&mattr);
|
||||
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(cli_rt->mutex, &mattr);
|
||||
cli_rt->msg_mutex = malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(cli_rt->msg_mutex, &mattr);
|
||||
pthread_mutexattr_destroy(&mattr);
|
||||
|
||||
cli_rt->context = ctx;
|
||||
JS_SetContextOpaque(ctx, cli_rt);
|
||||
JS_SetInterruptHandler(ctx, (JSInterruptHandler *)actor_interrupt_cb, cli_rt);
|
||||
|
||||
JS_AddGCRef(ctx, &cli_rt->idx_buffer_ref);
|
||||
JS_AddGCRef(ctx, &cli_rt->on_exception_ref);
|
||||
JS_AddGCRef(ctx, &cli_rt->message_handle_ref);
|
||||
JS_AddGCRef(ctx, &cli_rt->unneeded_ref);
|
||||
JS_AddGCRef(ctx, &cli_rt->actor_sym_ref);
|
||||
cli_rt->idx_buffer_ref.val = JS_NULL;
|
||||
cli_rt->on_exception_ref.val = JS_NULL;
|
||||
cli_rt->message_handle_ref.val = JS_NULL;
|
||||
cli_rt->unneeded_ref.val = JS_NULL;
|
||||
cli_rt->actor_sym_ref.val = JS_NewObject(ctx);
|
||||
|
||||
root_cell = cli_rt;
|
||||
|
||||
JS_FreeValue(ctx, js_blob_use(ctx));
|
||||
|
||||
JSValue hidden_env = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, hidden_env, "os", js_os_use(ctx));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "core_path", JS_NewString(ctx, core_path));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "use_mcode", JS_NewBool(ctx, use_mcode));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "actorsym", JS_NewObject(ctx));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "actorsym", JS_DupValue(ctx, cli_rt->actor_sym_ref.val));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "json", js_json_use(ctx));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "nota", js_nota_use(ctx));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "wota", js_wota_use(ctx));
|
||||
@@ -349,7 +379,7 @@ int cell_init(int argc, char **argv)
|
||||
} else {
|
||||
cJSON *ast = cJSON_Parse(boot_data);
|
||||
free(boot_data);
|
||||
if (!ast) { printf("Failed to parse bootstrap AST\n"); JS_FreeContext(ctx); JS_FreeRuntime(rt); return 1; }
|
||||
if (!ast) { printf("Failed to parse bootstrap AST\n"); JS_FreeContext(ctx); JS_FreeRuntime(g_runtime); return 1; }
|
||||
result = JS_RunMachTree(ctx, ast, hidden_env);
|
||||
cJSON_Delete(ast);
|
||||
}
|
||||
@@ -366,8 +396,32 @@ int cell_init(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (scheduler_actor_count() > 0) {
|
||||
actor_loop();
|
||||
exit_handler();
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
/* No actors spawned — clean up CLI context */
|
||||
JS_DeleteGCRef(ctx, &cli_rt->idx_buffer_ref);
|
||||
JS_DeleteGCRef(ctx, &cli_rt->on_exception_ref);
|
||||
JS_DeleteGCRef(ctx, &cli_rt->message_handle_ref);
|
||||
JS_DeleteGCRef(ctx, &cli_rt->unneeded_ref);
|
||||
JS_DeleteGCRef(ctx, &cli_rt->actor_sym_ref);
|
||||
JS_SetInterruptHandler(ctx, NULL, NULL);
|
||||
|
||||
pthread_mutex_destroy(cli_rt->mutex);
|
||||
free(cli_rt->mutex);
|
||||
pthread_mutex_destroy(cli_rt->msg_mutex);
|
||||
free(cli_rt->msg_mutex);
|
||||
free(cli_rt);
|
||||
root_cell = NULL;
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
JS_FreeRuntime(g_runtime);
|
||||
g_runtime = NULL;
|
||||
|
||||
exit_handler();
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ int actor_interrupt_cb(JSRuntime *rt, cell_rt *crt);
|
||||
void actor_loop();
|
||||
void actor_initialize(void);
|
||||
void actor_free(cell_rt *actor);
|
||||
int scheduler_actor_count(void);
|
||||
|
||||
uint64_t cell_ns();
|
||||
void cell_sleep(double seconds);
|
||||
|
||||
@@ -303,14 +303,29 @@ void actor_free(cell_rt *actor)
|
||||
free(actor);
|
||||
|
||||
int actor_count = lockless_shlen(actors);
|
||||
if (actor_count == 0) exit(0);
|
||||
if (actor_count == 0) {
|
||||
pthread_mutex_lock(&engine.lock);
|
||||
engine.shutting_down = 1;
|
||||
pthread_cond_broadcast(&engine.wake_cond);
|
||||
pthread_cond_broadcast(&engine.timer_cond);
|
||||
pthread_cond_broadcast(&engine.main_cond);
|
||||
pthread_mutex_unlock(&engine.lock);
|
||||
}
|
||||
}
|
||||
|
||||
int scheduler_actor_count(void) {
|
||||
return (int)lockless_shlen(actors);
|
||||
}
|
||||
|
||||
void exit_handler(void) {
|
||||
static int already_exiting = 0;
|
||||
if (already_exiting) return;
|
||||
already_exiting = 1;
|
||||
|
||||
pthread_mutex_lock(&engine.lock);
|
||||
engine.shutting_down = 1;
|
||||
pthread_cond_broadcast(&engine.wake_cond);
|
||||
pthread_cond_broadcast(&engine.timer_cond);
|
||||
pthread_cond_broadcast(&engine.wake_cond);
|
||||
pthread_cond_broadcast(&engine.timer_cond);
|
||||
pthread_cond_broadcast(&engine.main_cond);
|
||||
pthread_mutex_unlock(&engine.lock);
|
||||
|
||||
@@ -319,19 +334,17 @@ void exit_handler(void) {
|
||||
for (int i=0; i < engine.num_workers; i++) {
|
||||
pthread_join(engine.worker_threads[i], NULL);
|
||||
}
|
||||
|
||||
|
||||
free(engine.worker_threads);
|
||||
pthread_mutex_destroy(&engine.lock);
|
||||
pthread_cond_destroy(&engine.wake_cond);
|
||||
pthread_cond_destroy(&engine.timer_cond);
|
||||
pthread_cond_destroy(&engine.main_cond);
|
||||
|
||||
|
||||
pthread_mutex_destroy(actors_mutex);
|
||||
free(actors_mutex);
|
||||
|
||||
|
||||
arrfree(timer_heap);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int actor_exists(const char *id)
|
||||
|
||||
Reference in New Issue
Block a user