From 9277a27ce4527ea17cebb9529f26203650d09056 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 15 Jun 2020 14:16:10 +0100 Subject: util.gc: New module for configuring the Lua garbage collector --- util/gc.lua | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 util/gc.lua diff --git a/util/gc.lua b/util/gc.lua new file mode 100644 index 00000000..e02e85c4 --- /dev/null +++ b/util/gc.lua @@ -0,0 +1,50 @@ +local array = require "util.array"; +local set = require "util.set"; + +local known_options = { + incremental = set.new { "mode", "threshold", "speed", "step_size" }; + generational = set.new { "mode", "minor_threshold", "major_threshold" }; +}; + +if _VERSION ~= "5.4" then + known_options.generational = nil; + known_options.incremental:remove("step_size"); +end + +local function configure(user, defaults) + local mode = user.mode or defaults.mode or "incremental"; + if not known_options[mode] then + return nil, "GC mode not supported on ".._VERSION..": "..mode; + end + + for k, v in pairs(user) do + if not known_options[mode]:contains(k) then + return nil, "Unknown GC parameter: "..k; + elseif k ~= "mode" and type(v) ~= "number" then + return nil, "parameter '"..k.."' should be a number"; + end + end + + if mode == "incremental" then + if _VERSION == "Lua 5.4" then + collectgarbage(mode, + user.threshold or defaults.threshold, + user.speed or defaults.speed, + user.step_size or defaults.step_size + ); + else + collectgarbage("setpause", user.threshold or defaults.threshold); + collectgarbage("setstepmul", user.speed or defaults.speed); + end + elseif mode == "generational" then + collectgarbage(mode, + user.minor_threshold or defaults.minor_threshold, + user.major_threshold or defaults.major_threshold + ); + end + return true; +end + +return { + configure = configure; +}; -- cgit v1.2.3 From 42ff12bb04548d882b06d5d3de198aa9e74d9081 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 15 Jun 2020 14:23:47 +0100 Subject: util.gc: Linter fixes [luacheck] --- util/gc.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/util/gc.lua b/util/gc.lua index e02e85c4..b400af6b 100644 --- a/util/gc.lua +++ b/util/gc.lua @@ -1,4 +1,3 @@ -local array = require "util.array"; local set = require "util.set"; local known_options = { @@ -41,7 +40,7 @@ local function configure(user, defaults) user.minor_threshold or defaults.minor_threshold, user.major_threshold or defaults.major_threshold ); - end + end return true; end -- cgit v1.2.3 From c313b10cd98e8461bc1f17c6e7f47e90e0d3c379 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 15 Jun 2020 14:16:34 +0100 Subject: util.startup: Configure the GC on startup, using the config or built-in defaults --- util/startup.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/util/startup.lua b/util/startup.lua index 2a7e8a36..c1f4ec8b 100644 --- a/util/startup.lua +++ b/util/startup.lua @@ -12,6 +12,8 @@ local dependencies = require "util.dependencies"; local original_logging_config; +local default_gc_params = { mode = "incremental", threshold = 105, speed = 250 }; + local short_params = { D = "daemonize", F = "no-daemonize" }; local value_params = { config = true }; @@ -544,6 +546,19 @@ function startup.check_unwriteable() end end +function startup.init_gc() + -- Apply garbage collector settings from the config file + local gc = require "util.gc"; + local gc_settings = config.get("*", "gc") or { mode = default_gc_params.mode }; + + local ok, err = gc.configure(gc_settings, default_gc_params); + if not ok then + log("error", "Failed to apply GC configuration: %s", err); + return nil, err; + end + return true; +end + function startup.make_host(hostname) return { type = "local", @@ -573,6 +588,7 @@ function startup.prosodyctl() startup.read_config(); startup.force_console_logging(); startup.init_logging(); + startup.init_gc(); startup.setup_plugindir(); startup.setup_datadir(); startup.chdir(); @@ -593,6 +609,7 @@ function startup.prosody() startup.init_global_state(); startup.read_config(); startup.init_logging(); + startup.init_gc(); startup.sanity_check(); startup.sandbox_require(); startup.set_function_metatable(); -- cgit v1.2.3