diff --git a/docs/changes.md b/docs/changes.md index 7f74315..49564f3 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -61,6 +61,9 @@ Table of contents # Update 16.0.0 - Connecting the dots Added --- +- multi:setCurrentProcess() -- Used to set the current processor. It should only be called on a processor object +- multi.warn(...) -- Sends a warning. +- multi.error(err) -- When called this function will gracefully kill multi, cleaning things up. - THREAD.setENV(table) -- Set a simple table that will be merged into the global namespace **Note:** To maintain compatibility between each integration use simple tables. No self references, and string indices only @@ -201,6 +204,7 @@ Added Changed --- +- multi.print shows "INFO" before it's message. - Connections internals changed, not too much changed on the surface. - newConnection(protect, func, kill) - `protect` disables fastmode, but protects the connection diff --git a/init.lua b/init.lua index a38ab30..6870b9c 100644 --- a/init.lua +++ b/init.lua @@ -178,7 +178,7 @@ function multi:newConnection(protect, func, kill) cn:Fire(obj1(...)) end) else - error("Invalid mod!", type(obj1), type(obj2),"Expected function, connection(table)") + multi.error("Invalid mod!", type(obj1), type(obj2),"Expected function, connection(table)") end return cn end, @@ -210,7 +210,7 @@ function multi:newConnection(protect, func, kill) end) end else - error("Invalid concat!", type(obj1), type(obj2),"Expected function/connection(table), connection(table)/function") + multi.error("Invalid concat!", type(obj1), type(obj2),"Expected function/connection(table), connection(table)/function") end return cn end, @@ -576,7 +576,7 @@ end --Constructors [CORE] local _tid = 0 function multi:newBase(ins) - if not(self.Type=='rootprocess' or self.Type=='process') then error('Can only create an object on multi or an interface obj') return false end + if not(self.Type=='rootprocess' or self.Type=='process') then multi.error('Can only create an object on multi or an interface obj') return false end local c = {} if self.Type=='process' then setmetatable(c, {__index = multi}) @@ -1187,7 +1187,7 @@ function thread.hold(n,opt) elseif type(n) == "function" then return yield(CMD, t_hold, n or dFunc, nil, interval) else - error("Invalid argument passed to thread.hold(...)!") + multi.error("Invalid argument passed to thread.hold(...)!") end end @@ -1207,7 +1207,7 @@ function thread.skip(n) end function thread.kill() - error("thread killed!") + multi.error("thread killed!") end function thread.yield() @@ -1759,7 +1759,7 @@ function multi:newService(func) -- Priority managed threads end -- Multi runners -local function mainloop(self) +function multi:mainloopRef() __CurrentProcess = self multi.OnPreLoad:Fire() self.uManager = self.uManagerRef @@ -1782,9 +1782,9 @@ local function mainloop(self) end end -multi.mainloop = mainloop +multi.mainloop = multi.mainloopRef -local function p_mainloop(self) +function multi:p_mainloop() __CurrentProcess = self multi.OnPreLoad:Fire() self.uManager = self.uManagerRefP1 @@ -1859,11 +1859,15 @@ local function doOpt() end return yield(CMD, t_hold, n or dFunc, nil, interval) else - error("Invalid argument passed to thread.hold(...)!") + multi.error("Invalid argument passed to thread.hold(...)!") end end end +function multi:setCurrentProcess() + __CurrentProcess = self +end + local init = false function multi.init(settings, realsettings) if settings == multi then settings = realsettings end @@ -1872,9 +1876,9 @@ function multi.init(settings, realsettings) if type(settings)=="table" then multi.defaultSettings = settings if settings.priority then - multi.mainloop = p_mainloop + multi.mainloop = multi.p_mainloop else - multi.mainloop = mainloop + multi.mainloop = multi.mainloopRef end if settings.findopt then find_optimization = true @@ -2195,10 +2199,20 @@ end function multi.print(...) if multi.defaultSettings.print then - print(...) + print("INFO:", table.concat({...}, " ")) end end +function multi.warn(...) + if multi.defaultSettings.warn then + print("WARNING:", table.concat({...}, " ")) + end +end + +function multi.error(err) + error("ERROR: " .. err) +end + multi.GetType = multi.getType multi.IsPaused = multi.isPaused multi.IsActive = multi.isActive diff --git a/integration/priorityManager/init.lua b/integration/priorityManager/init.lua new file mode 100644 index 0000000..ca5db00 --- /dev/null +++ b/integration/priorityManager/init.lua @@ -0,0 +1,81 @@ +-- Advanced process management. Mutates the multi namespace +local multi, thread = require("multi"):init() +local ok, chronos = pcall(require, "chronos") -- hpc + +if not ok then chronos = nil end + +-- This is an integration, we cannot directly access locals that are in the main file. + +local PList = { + multi.Priority_Core, + multi.Priority_Very_High, + multi.Priority_High, + multi.Priority_Above_Normal, + multi.Priority_Normal, + multi.Priority_Below_Normal, + multi.Priority_Low, + multi.Priority_Very_Low, + multi.Priority_Idle +} + +-- Restructered these functions since they rely on local variables from the core library + +local mainloop = multi.mainloopRef +local mainloop_p = multi.mainloop_p +local uManagerRef = multi.uManagerRef +local uManagerRefP = multi.uManagerRefP1 + +-- self:setCurrentProcess() a bit slower than using the local var, but there isn't another option + +-- function multi:uManagerRef() +-- if self.Active then +-- self:setCurrentProcess() +-- local Loop=self.Mainloop +-- for _D=#Loop,1,-1 do +-- __CurrentTask = Loop[_D] +-- __CurrentTask:Act() +-- self:setCurrentProcess() +-- end +-- end +-- end + +local function init() + local RR, PB, TB = 0, 1, 2 + + multi.priorityScheme = { + RoundRobin = 0, + PriorityBased = 1, + TimedBased = 2 + } + + function multi:setPriorityScheme(scheme) + if not self.Type == multi.PROCESS or not self.Type == multi.ROOTPROCESS then + multi.warn("You should only invoke setPriorityScheme on a processor object!") + end + if scheme == RR then + multi.mainloop = mainloop + multi.uManager = uManagerRef + elseif scheme == PB then + multi.mainloop = mainloop_p + multi.uManager = uManagerRefP + elseif scheme == TB then + -- + else + multi.error("Invalid priority scheme passed!") + end + end +end + +local function init_chronos() + +end + +if chronos then + init_chronos() +else + multi.print("In order to have time based priority management, you need to install the chronos library!") +end + +init() + +--chronos.nanotime() \ No newline at end of file