1#!/usr/local/bin/recon 2 3local benchrun = require 'benchrun' 4local perfdata = require 'perfdata' 5local csv = require 'csv' 6local sysctl = require 'sysctl' 7 8require 'strict' 9 10local kDefaultDuration = 15 11 12local benchmark = benchrun.new { 13 name = 'xnu.perf_compressor', 14 version = 1, 15 arg = arg, 16 modify_argparser = function(parser) 17 parser:argument { 18 name = 'path', 19 description = 'Path to perf_compressor binary' 20 } 21 parser:option{ 22 name = '--duration', 23 description = 'How long, in seconds, to run each iteration', 24 default = kDefaultDuration 25 } 26 parser:option{ 27 name = '--variant', 28 description = 'Which benchmark variant to run', 29 default = 'compress-and-decompress', 30 choices = {'compress', 'compress-and-decompress'} 31 } 32 parser:option{ 33 name = '--buffer-size', 34 description = 'MB size of buffer to send to compressor', 35 default = 100 36 } 37 parser:option{ 38 name = '--data-type', 39 description = 'Fill the buffer with random, zero, or typical data', 40 default = 'typical', 41 choices = {'typical', 'random', 'zero'} 42 } 43 parser:flag { 44 name = '--verbose', 45 description = 'Print benchmark progress', 46 } 47 end 48} 49local is_development_kernel, err = sysctl("kern.development") 50benchmark:assert(err == nil, "Unable to check for development kernel") 51if is_development_kernel == 0 then 52 print "Skipping benchmark on non-development kernel." 53 os.exit(0) 54end 55local hw_page_size, err = sysctl("hw.pagesize") 56benchmark:assert(err == nil, "Unable to check hw page size") 57local vm_page_size, err = sysctl("vm.pagesize") 58benchmark:assert(err == nil, "Unable to check vm page size") 59local product_name = benchmark:spawn{'/usr/bin/sw_vers', '-productName'} 60if hw_page_size ~= vm_page_size then 61 benchmark:print "Skipping benchmark on this platform because benchmark process has a different page size than the kernel" 62 os.exit(0) 63elseif string.find(product_name, "Watch OS") or string.find(product_name, "TVOS") then 64 -- rdar://119044527: Temporarily disable test for watchOS and tvOS 65 benchmark:print "Skipping benchmark on this platform as a temporary workaround to avoid device panics" 66 os.exit(0) 67end 68 69args = {benchmark.opt.path, benchmark.opt.variant, benchmark.opt.data_type, benchmark.opt.duration, benchmark.opt.buffer_size} 70if benchmark.opt.verbose then 71 table.insert(args, 2, "-v") 72 args["echo"] = true 73end 74for out in benchmark:run(args) do 75 local result = out:match("-----Results-----\n(.*)") 76 benchmark:assert(result, "Unable to find result data in output") 77 local data = csv.openstring(result, {header = true}) 78 for field in data:lines() do 79 for k, v in pairs(field) do 80 unit = perfdata.unit.bytes_per_second 81 if k == "Compression Ratio" then 82 unit = perfdata.unit.custom("uncompressed / compressed") 83 end 84 benchmark.writer:add_value(k, unit, tonumber(v), { 85 data_type = benchmark.opt.data_type, 86 buffer_size = benchmark.opt.buffer_size, 87 [perfdata.larger_better] = true 88 }) 89 end 90 end 91end 92 93benchmark:finish() 94