From c124a650df1cb66eb225fe7f30848eb78b9309b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Wed, 9 Jul 2014 17:00:06 +0200 Subject: [PATCH] Improved performance of component callbacks. Enforcing tighter time limit on user __gc methods. --- .../assets/opencomputers/lua/kernel.lua | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/resources/assets/opencomputers/lua/kernel.lua b/src/main/resources/assets/opencomputers/lua/kernel.lua index eb8a43aa8..c22002102 100644 --- a/src/main/resources/assets/opencomputers/lua/kernel.lua +++ b/src/main/resources/assets/opencomputers/lua/kernel.lua @@ -80,12 +80,19 @@ sandbox = { setmetatable = function(t, mt) local gc = rawget(mt, "__gc") if type(gc) == "function" then + -- For all user __gc functions we enforce a much tighter deadline. + -- This is because these functions may be called from the main + -- thread under certain circumstanced (such as when saving the world), + -- which can lead to noticeable lag if the __gc function behaves badly. rawset(mt, "__gc", function(self) + local oldDeadline, oldHitDeadline = deadline, hitDeadline local co = coroutine.create(gc) debug.sethook(co, checkDeadline, "", hookInterval) + deadline, hitDeadline = math.min(oldDeadline, computer.realTime() + 0.5), true local result, reason = coroutine.resume(co, self) debug.sethook(co) checkDeadline() + deadline, hitDeadline = oldDeadline, oldHitDeadline if not result then error(reason, 0) end @@ -440,17 +447,18 @@ end local libcomponent +local proxyCache = setmetatable({}, {__mode="v"}) +local proxyDirectCache = setmetatable({}, {__mode="v"}) + local componentCallback = { __call = function(self, ...) - return libcomponent.invoke(self.address, self.name, ...) + return invoke(component, not not proxyDirectCache[self], self.address, self.name, ...) end, __tostring = function(self) return libcomponent.doc(self.address, self.name) or "function" end } -local proxyCache = setmetatable({}, {__mode="v"}) - libcomponent = { doc = function(address, method) checkArg(1, address, "string") @@ -500,8 +508,9 @@ libcomponent = { if not methods then return nil, reason end - for method in pairs(methods) do + for method, direct in pairs(methods) do proxy[method] = setmetatable({address=address,name=method}, componentCallback) + proxyDirectCache[proxy[method]] = direct end proxyCache[address] = proxy return proxy