summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-12-20 12:16:29 +0800
committerGitHub <[email protected]>2024-12-20 12:16:29 +0800
commitc8222c8a893e2e82c1f6fbb8f894fba24398f33a (patch)
treeb3e2c004c7c5deef2fea2fce366cd105dbcffd49
parentca53159567407c93e948c265fa9c36fbcb1752bc (diff)
parent0b000b3edb52bc2b9b981f7208a4634df7d85d12 (diff)
Merge pull request #5993 from xmake-io/profile
Profile process perf
-rw-r--r--xmake/core/base/os.lua71
-rw-r--r--xmake/core/base/profiler.lua2
2 files changed, 72 insertions, 1 deletions
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 6a1151e23..c1675196b 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -279,8 +279,48 @@ function os._is_tracing_process()
return is_tracing
end
+-- profile process performance?
+function os._is_profiling_process_perf()
+ local is_profiling = os._IS_PROFILING_PROCESS_PERF
+ if is_profiling == nil then
+ local profile = os.getenv("XMAKE_PROFILE")
+ if profile then
+ profile = profile:trim()
+ if profile == "perf:process" then
+ is_profiling = true
+ end
+ end
+ is_profiling = is_profiling or false
+ os._IS_PROFILING_PROCESS_PERF = is_profiling
+ end
+ return is_profiling
+end
+
-- run all exit callback
function os._run_exit_cbs(ok, errors)
+
+ -- show process performance reports
+ local profileperf = os._is_profiling_process_perf()
+ if profileperf then
+ if os._PROCESS_PROFILEINFO then
+ local perfinfo = {}
+ local totaltime = 0
+ for runcmd, profileinfo in pairs(os._PROCESS_PROFILEINFO) do
+ profileinfo.runcmd = runcmd
+ totaltime = totaltime + profileinfo.totaltime
+ table.insert(perfinfo, profileinfo)
+ end
+ table.sort(perfinfo, function (a, b) return a.totaltime > b.totaltime end)
+ for _, profileinfo in ipairs(perfinfo) do
+ local percent = (profileinfo.totaltime / totaltime) * 100
+ if percent < 1 then
+ break
+ end
+ utils.print("%6.3f, %6.2f%%, %7d, %s", profileinfo.totaltime, percent, profileinfo.runcount, profileinfo.runcmd)
+ end
+ end
+ end
+
local exit_callbacks = os._EXIT_CALLBACKS
if exit_callbacks then
for _, cb in ipairs(exit_callbacks) do
@@ -905,6 +945,13 @@ function os.execv(program, argv, opt)
detach = opt.detach,
exclusive = opt.exclusive}
+ -- profile process performance
+ local runtime
+ local profileperf = os._is_profiling_process_perf()
+ if profileperf then
+ runtime = os.mclock()
+ end
+
-- open command
local ok = -1
local errors
@@ -936,6 +983,30 @@ function os.execv(program, argv, opt)
-- close process
proc:close()
+
+ -- save profile info
+ if profileperf then
+ runtime = os.mclock() - runtime
+
+ local profileinfo = os._PROCESS_PROFILEINFO
+ if profileinfo == nil then
+ profileinfo = {}
+ os._PROCESS_PROFILEINFO = profileinfo
+ end
+
+ local runcmd
+ runcmd = filename
+ if argv and #argv > 0 then
+ runcmd = runcmd .. " " .. os.args(argv)
+ end
+ local perfinfo = profileinfo[runcmd]
+ if perfinfo == nil then
+ perfinfo = {}
+ profileinfo[runcmd] = perfinfo
+ end
+ perfinfo.totaltime = (perfinfo.totaltime or 0) + runtime
+ perfinfo.runcount = (perfinfo.runcount or 0) + 1
+ end
else
-- cannot execute process
return nil, os.strerror()
diff --git a/xmake/core/base/profiler.lua b/xmake/core/base/profiler.lua
index 331f02c5e..ae0ced4fc 100644
--- a/xmake/core/base/profiler.lua
+++ b/xmake/core/base/profiler.lua
@@ -247,7 +247,7 @@ function profiler:leave(name, ...)
end
end
--- get profiler mode, e.g. perf:call, perf:tag, trace
+-- get profiler mode, e.g. perf:call, perf:tag, perf:process, trace
function profiler:mode()
local mode = self._MODE
if mode == nil then