From 8b976dd744fc18d617e00655631cbca8a1f19035 Mon Sep 17 00:00:00 2001 From: ruki Date: Sun, 27 Apr 2025 22:33:55 +0800 Subject: optimize thread load/save --- xmake/core/thread/thread.lua | 57 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 12 deletions(-) (limited to 'xmake/core/thread/thread.lua') diff --git a/xmake/core/thread/thread.lua b/xmake/core/thread/thread.lua index 9571c981b..dcb74e282 100644 --- a/xmake/core/thread/thread.lua +++ b/xmake/core/thread/thread.lua @@ -92,11 +92,12 @@ function _instance:start() assert(not self:cdata()) -- serialize and pass callback and arguments to this thread - local callinfo = { - callback = self._CALLBACK, - argv = self._ARGV - } - callinfo = string.serialize(callinfo, {strip = true, indent = false}) + -- we do not use string.serialize to serialize callback, because it's slower (deserialize) + local callinfo = string._dump(self._CALLBACK, true) + local argv = self._ARGV + if argv ~= nil then + callinfo = string.serialize(argv, {strip = true, indent = false}) .. "" .. callinfo + end -- init and start thread local handle, errors = thread.thread_init(self:name(), callinfo, self._STACKSIZE) @@ -205,14 +206,46 @@ end -- run thread function thread._run_thread(callinfo_str) - -- get callback info - local callinfo, errors = string.deserialize(callinfo_str) - if not callinfo then - return false, string.format("invalid thread callinfo, %s!", errors or "unknown") + -- get callinfo + local parts = callinfo_str:split("", {plain = true}) + local callback_str, argv_str + if #parts > 1 then + callback_str = parts[2] + argv_str = parts[1] + else + callback_str = parts[1] + end + + -- load callback + local fenv = debug.getfenv(debug.getinfo(2, "f").func) + local callback + if callback_str then + local script, errors = load(callback_str, "=(thread)", "b", fenv) + if not script then + return false, string.format("cannot load thread callback, %s!", errors or "unknown") + end + --[[ + for i = 1, math.huge do + local upname, upvalue = debug.getupvalue(script, i) + if upname == nil or upname == "" then + break + end + print("upname", i, upname, upvalue) + end]] + callback = script end - local callback = callinfo.callback if not callback then - return false, string.format("no callback") + return false, "no thread callback" + end + + -- load argument list + local argv + if argv_str then + local result, errors = string.deserialize(argv_str) + if not result then + return false, string.format("invalid thread arguments, %s!", errors or "unknown") + end + argv = result end -- bind sandbox @@ -224,7 +257,7 @@ function thread._run_thread(callinfo_str) end -- do callback - return sandbox.load(sandbox_inst:script(), table.unpack(callinfo.argv or {})) + return sandbox.load(sandbox_inst:script(), table.unpack(argv or {})) end -- return module -- cgit v1.3.1