Skip to content

Conversation

@Sythivo
Copy link
Contributor

@Sythivo Sythivo commented Jan 5, 2026

Fixes #703

NOTE: This may present blocking bugs on any lute API that does not use libuv, and uses scheduler completion/continuation.

@Vighnesh-V
Copy link
Collaborator

Thanks for contributing! Question - would your PR block on the following:

local task = require("@lute/task")
task.spawn(function() 
    task.wait(100)
    print("Hello")
end)
task.wait(100000)

Ideally, this will print "Hello" every 0.1s - the fact that the main thread is 'blocked' shouldn't prevent other threads from doing useful work. I'm a little confused about the comment you left re:

may present blocking bugs on lute apis that use scheduler completion/continuation.
  • most async calls probably do use scheduler completion / continuation. Could you give an example of why not using the libuv call but scheduling continutations might break down?

@Sythivo
Copy link
Contributor Author

Sythivo commented Jan 6, 2026

Thanks for contributing! Question - would your PR block on the following:

local task = require("@lute/task")
task.spawn(function() 
    task.wait(100)
    print("Hello")
end)
task.wait(100000)

The PR does not block that, just tested this, I have put 0.1 seconds instead of 100 when testing this, since 100 seconds is way too long to test.

Ideally, this will print "Hello" every 0.1s - the fact that the main thread is 'blocked' shouldn't prevent other threads from doing useful work. I'm a little confused about the comment you left re:

may present blocking bugs on lute apis that use scheduler completion/continuation.
  • most async calls probably do use scheduler completion / continuation. Could you give an example of why not using the libuv call but scheduling continutations might break down?

This was mostly from what I read on the libuv docs about the UV_RUN_ONCE behavior, stating it would block even on empty callbacks. libuv docs

UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if there are no pending callbacks. Returns zero when done (no active handles or requests left), or non-zero if more callbacks are expected (meaning you should run the event loop again sometime in the future).

@Vighnesh-V
Copy link
Collaborator

We looked over this again recently - I think the main issue here is that there are continuations that have to be processed after this uv_run call. If uv_run blocks, then we'll never get to those continuations.

I spoke with the team and I think there is a more systematic fix we can do here. Part of the issue that you identified is that we are continuously running the event loop to do work, which is probably contributing to high cpu usage. The other part is that we are tracking work in multiple places - in the runtime as well as the uv event loop. I think we can make it so that all work, including continuations etc get scheduled on the libuv event loop - that way outstanding work gets processed when we call uv_run and we can block in one place without consuming too much cpu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

High CPU usage when runtime idling

2 participants