From a15bb8e99483d1c14d240b110e69ddc8f43fd735 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Wed, 21 Aug 2024 12:53:38 -0400 Subject: [PATCH] Don't rely on being idle to do anything. Fixes JS job starvation on slow machines more. --- src/task.c | 44 +++++++++----------------------------------- src/task.h | 7 +++++++ src/util.js.c | 4 ++-- 3 files changed, 18 insertions(+), 37 deletions(-) diff --git a/src/task.c b/src/task.c index 0af81a2f..04b802e1 100644 --- a/src/task.c +++ b/src/task.c @@ -141,8 +141,6 @@ typedef struct _tf_task_t float thread_percent; uv_async_t run_jobs_async; - uv_idle_t idle; - uv_prepare_t prepare; uv_signal_t sig_term; uv_signal_t sig_int; @@ -209,7 +207,6 @@ static void _tf_task_sendPromiseExportMessage(tf_task_t* from, tf_taskstub_t* to static JSValue _tf_task_executeSource(tf_task_t* task, const char* source, const char* name); static tf_taskstub_t* _tf_task_get_stub(tf_task_t* task, taskid_t id); static void _tf_task_release_export(tf_taskstub_t* stub, exportid_t exportId); -static void _tf_task_run_jobs_prepare(uv_prepare_t* prepare); static void _timeout_unlink(tf_task_t* task, timeout_t* timeout); static void _timeout_closed(uv_handle_t* handle); @@ -1522,28 +1519,6 @@ static bool _tf_task_run_jobs(tf_task_t* task) return 0; } -static void _tf_task_run_jobs_idle(uv_idle_t* idle) -{ - tf_task_t* task = idle->data; - if (!_tf_task_run_jobs(task)) - { - /* No more jobs. Don't try again as actively. */ - uv_idle_stop(&task->idle); - uv_prepare_start(&task->prepare, _tf_task_run_jobs_prepare); - } -} - -static void _tf_task_run_jobs_prepare(uv_prepare_t* prepare) -{ - tf_task_t* task = prepare->data; - if (_tf_task_run_jobs(task)) - { - /* More jobs. We can run again immediately. */ - uv_idle_start(&task->idle, _tf_task_run_jobs_idle); - uv_prepare_stop(&task->prepare); - } -} - static void _tf_task_run_jobs_async(uv_async_t* async) { tf_task_t* task = async->data; @@ -1553,6 +1528,14 @@ static void _tf_task_run_jobs_async(uv_async_t* async) } } +void tf_task_check_jobs(tf_task_t* task) +{ + if (JS_IsJobPending(task->_runtime)) + { + uv_async_send(&task->run_jobs_async); + } +} + static JSModuleDef* _tf_task_module_loader(JSContext* context, const char* module_name, void* opaque) { tf_task_t* task = opaque; @@ -1646,13 +1629,6 @@ tf_task_t* tf_task_create() uv_timer_init(&task->_loop, &task->gc_timer); uv_timer_start(&task->gc_timer, _tf_task_gc_timer, 1000, 1000); uv_unref((uv_handle_t*)&task->gc_timer); - task->idle.data = task; - uv_idle_init(&task->_loop, &task->idle); - uv_unref((uv_handle_t*)&task->idle); - task->prepare.data = task; - uv_prepare_init(&task->_loop, &task->prepare); - uv_unref((uv_handle_t*)&task->prepare); - uv_idle_start(&task->idle, _tf_task_run_jobs_idle); task->run_jobs_async.data = task; uv_async_init(&task->_loop, &task->run_jobs_async, _tf_task_run_jobs_async); uv_unref((uv_handle_t*)&task->run_jobs_async); @@ -1923,15 +1899,13 @@ void tf_task_destroy(tf_task_t* task) { uv_close((uv_handle_t*)&task->gc_timer, _tf_task_on_handle_close); } - uv_close((uv_handle_t*)&task->idle, _tf_task_on_handle_close); - uv_close((uv_handle_t*)&task->prepare, _tf_task_on_handle_close); uv_close((uv_handle_t*)&task->run_jobs_async, _tf_task_on_handle_close); uv_signal_stop(&task->sig_term); uv_close((uv_handle_t*)&task->sig_term, _tf_task_on_handle_close); uv_signal_stop(&task->sig_int); uv_close((uv_handle_t*)&task->sig_int, _tf_task_on_handle_close); - while (task->trace_timer.data || task->gc_timer.data || task->idle.data || task->prepare.data || task->run_jobs_async.data || task->sig_term.data || task->sig_int.data) + while (task->trace_timer.data || task->gc_timer.data || task->run_jobs_async.data || task->sig_term.data || task->sig_int.data) { uv_run(&task->_loop, UV_RUN_ONCE); } diff --git a/src/task.h b/src/task.h index 7d81d2c6..c23263fb 100644 --- a/src/task.h +++ b/src/task.h @@ -364,4 +364,11 @@ tf_android_start_service_t* tf_task_get_android_start_service(); */ tf_android_stop_service_t* tf_task_get_android_stop_service(); +/** +** Check for JS jobs that need to be run. Generally to be called post-JS_Call +** in tf_util_report_error. +** @param task The task. +*/ +void tf_task_check_jobs(tf_task_t* task); + /** @} */ diff --git a/src/util.js.c b/src/util.js.c index b98d6702..3095b306 100644 --- a/src/util.js.c +++ b/src/util.js.c @@ -211,6 +211,7 @@ static JSValue _util_print(JSContext* context, JSValueConst this_val, int argc, bool tf_util_report_error(JSContext* context, JSValue value) { bool is_error = false; + tf_task_t* task = tf_task_get(context); if (JS_IsError(context, value)) { const char* string = JS_ToCString(context, value); @@ -226,13 +227,11 @@ bool tf_util_report_error(JSContext* context, JSValue value) } JS_FreeValue(context, stack); - tf_task_t* task = tf_task_get(context); tf_task_send_error_to_parent(task, value); is_error = true; } else if (JS_IsException(value)) { - tf_task_t* task = tf_task_get(context); if (!tf_task_send_error_to_parent(task, value)) { JSValue exception = JS_GetException(context); @@ -241,6 +240,7 @@ bool tf_util_report_error(JSContext* context, JSValue value) } is_error = true; } + tf_task_check_jobs(task); return is_error; }