#!/usr/local/bin/recon local benchrun = require 'benchrun' local perfdata = require 'perfdata' local csv = require 'csv' local sysctl = require 'sysctl' require 'strict' local kDefaultDuration = 15 local benchmark = benchrun.new { name = 'xnu.perf_compressor', version = 1, arg = arg, modify_argparser = function(parser) parser:argument { name = 'path', description = 'Path to perf_compressor binary' } parser:option{ name = '--duration', description = 'How long, in seconds, to run each iteration', default = kDefaultDuration } parser:option{ name = '--variant', description = 'Which benchmark variant to run', default = 'compress-and-decompress', choices = {'compress', 'compress-and-decompress'} } parser:option{ name = '--buffer-size', description = 'MB size of buffer to send to compressor', default = 100 } parser:option{ name = '--data-type', description = 'Fill the buffer with random, zero, or typical data', default = 'typical', choices = {'typical', 'random', 'zero'} } parser:flag { name = '--verbose', description = 'Print benchmark progress', } end } local is_development_kernel, err = sysctl("kern.development") benchmark:assert(err == nil, "Unable to check for development kernel") if is_development_kernel == 0 then print "Skipping benchmark on non-development kernel." os.exit(0) end local hw_page_size, err = sysctl("hw.pagesize") benchmark:assert(err == nil, "Unable to check hw page size") local vm_page_size, err = sysctl("vm.pagesize") benchmark:assert(err == nil, "Unable to check vm page size") local product_name = benchmark:spawn{'/usr/bin/sw_vers', '-productName'} if hw_page_size ~= vm_page_size then benchmark:print "Skipping benchmark on this platform because benchmark process has a different page size than the kernel" os.exit(0) elseif string.find(product_name, "Watch OS") or string.find(product_name, "TVOS") then -- rdar://103802544: Temporarily disable test for watchOS and tvOS benchmark:print "Skipping benchmark on this platform as a temporary workaround to avoid device panics" os.exit(0) end args = {benchmark.opt.path, benchmark.opt.variant, benchmark.opt.data_type, benchmark.opt.duration, benchmark.opt.buffer_size} if benchmark.opt.verbose then table.insert(args, 2, "-v") args["echo"] = true end for out in benchmark:run(args) do local result = out:match("-----Results-----\n(.*)") benchmark:assert(result, "Unable to find result data in output") local data = csv.openstring(result, {header = true}) for field in data:lines() do for k, v in pairs(field) do unit = perfdata.unit.bytes_per_second if k == "Compression Ratio" then unit = perfdata.unit.custom("uncompressed / compressed") end benchmark.writer:add_value(k, unit, tonumber(v), { data_type = benchmark.opt.data_type, buffer_size = benchmark.opt.buffer_size, [perfdata.larger_better] = true }) end end end benchmark:finish()