-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MANUAL MERGE] Async environment for mods to do concurrent tasks #11131
Conversation
Feedback wantedIf you have a mod that could benefit from offloading tasks into background thread(s) please take a look at this PR and give feedback if/how the current API would fit. -------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds to be a great start. Can't we do the whole async job from C++ instead of going to lua (i mean the core.job_processor part)
@sfan5 Would that be usable to do Lua MapGen without holding the big env lock? (I don't think so, but wanted to make sure) |
You could push mapgen tasks to async workers inside on_generated and then copy the result to the map once they're done but this has several problems and is a poor imitation of the real solution. So, no. |
|
Ordinarily yes, but in this case, no. This implementation is as simple as it gets since the async job code already exists.
Uh? Globals work fine and upvales can, by definition, not work when transferred into another Lua environment.
That's planned (the "• allow mods to register stuff to be imported at env init time" point). |
But you are using different globals. My point was that it's weird that you give a function as argument, which kinda looks like you could use everything that you normally use in a function. A string would make the difference clearer. |
Might be useful for transaction log files. Those should be rewritten every now and then, which should ideally happen in the background. A separate process could be spawned, but that's quite a workaround. |
I don't see why the (de)serialization overhead is necessary. As this uses a separate Lua state, copying Lua objects is of course necessary, but why can't this be done efficiently in C++ though? |
Copying the data directly between Lua states is tricky but possible if:
For anything else an intermediate format is necessary. |
One feature that would be useful but that I don't see in the API is a way to wait for a particular task to finish. This would allow for fork-join type multithreaded code. |
Wouldn't this be equivalent? local results = {}
local finish = function(ret)
results[#results+1] = ret
if #results == 5 then
-- do something with `results`
end
end
for i = 1,5 do
minetest.handle_async(function(obj)
-- do something with `obj`
return obj
end, finish, {foo="bar"})
end If by "wait" you meant a blocking wait then that's not really possible but you can use coroutines to emulate this. |
I did mean blocking. Ideally, doing computation in parallel should be an implementation detail of mods. It should not require redesigning the mods' code to be asynchronous. Blocking seems like it should be theoretically possible, although it might require changing a lot of the internal code. |
Couldn't you trivially implement blocking using a busywait? In sfan's code, |
I think the results of async jobs are only polled between ticks. |
Blocking would remove the benefit of concurrency. Perhaps you want coroutines ? |
If a newly started thread immediately exits then m_running would immediately be set to false again and the caller would be stuck waiting for m_running to become true forever. Since a mutex for synchronizing startup already exists we can simply move the while loop into it. see also: minetest#5134 which introduced m_start_finished_mutex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested the provided /flip
command and the devtest code. Works.
No newly introduced memory leaks found. 2x Conditional jump or move depends on uninitialised value(s)
which might be Lua false-positives.
Merged. |
basically #3375 by integrating the existing mechanism of async jobs that the mainmenu uses
make sure to read the new section in lua_api.txt
Merging
Async environment for mods to do concurrent tasks (#11131)
To do
This PR is Ready for Review.
VoxelManip
,ItemStack
, ...)core.registered_*
into async envIdeas:
How to test
Play around with/try the following
/a
: Execute any code in any async env, shows return values/return
: The same butreturn
is prepended for convenience (e.g./return _VERSION, type(_G), jit and jit.arch
)/err 1
or/err 2
: tests how errors inside the async env or return callback are reported/bitcoin
run an intensive background task based on the same principle as Bitcoin mining,which is finding hashes with chosen prefixes (null bytes)
/flip
flips a mapblocks but does the computation in another thread (worldedit required)