From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp55.i.mail.ru (smtp55.i.mail.ru [217.69.128.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 6B35145256A for ; Wed, 13 Nov 2019 21:04:25 +0300 (MSK) From: Serge Petrenko Date: Wed, 13 Nov 2019 21:04:01 +0300 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH 2/2] app/fiber: wait till a full event loop iteration ends. List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: v.shpilevoy@tarantool.org Cc: tarantool-patches@dev.tarantool.org fiber.top() fills in statistics every event loop iteration, so if it was just enabled, fiber.top() may contain 'inf's and 'nan's in fiber cpu usage averages because total time consumed by the main thread was not yet accounted for. Same stands for viewing top() results for a freshly created fiber: its metrics will be zero since it hasn't lived a full ev loop iteration yet. Fix this by delaying the test till top() results are meaningful and add minor refactoring. Follow-up #2694 --- test/app/fiber.result | 35 ++++++++++++++++++++++++++--------- test/app/fiber.test.lua | 31 +++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/test/app/fiber.result b/test/app/fiber.result index 4a094939f..d447a36fc 100644 --- a/test/app/fiber.result +++ b/test/app/fiber.result @@ -1469,6 +1469,19 @@ sum = 0 fiber.top_enable() --- ... +-- Check that a number is finite. +-- Lua doesn't have this, sorry. +function finite(num)\ + return type(num) == 'number' and num < math.huge and\ + num > -math.huge and tostring(num) ~= 'nan'\ +end +--- +... +-- Wait till a full event loop iteration passes, so that +-- top() contains meaningful results. +while not finite(fiber.top().cpu["1/sched"].instant) do fiber.yield() end +--- +... a = fiber.top() --- ... @@ -1504,9 +1517,9 @@ for k, v in pairs(a) do\ end --- ... -sum_inst +sum_inst > 99 and sum_inst < 101 or sum_inst --- -- 100 +- true ... -- not exact due to accumulated integer division errors sum_avg > 99 and sum_avg < 101 or sum_avg @@ -1517,24 +1530,28 @@ tbl = nil --- ... f = fiber.new(function()\ - for i = 1,1000 do end\ - fiber.yield()\ - tbl = fiber.top().cpu[fiber.self().id()..'/'..fiber.self().name()]\ + local fiber_key = fiber.self().id()..'/'..fiber.self().name()\ + tbl = fiber.top().cpu[fiber_key]\ + while tbl.time == 0 do\ + for i = 1,1000 do end\ + fiber.yield()\ + tbl = fiber.top().cpu[fiber_key]\ + end\ end) --- ... -while f:status() ~= 'dead' do fiber.sleep(0.01) end +while f:status() ~= 'dead' do fiber.yield() end --- ... -tbl["average"] > 0 +tbl.average > 0 --- - true ... -tbl["instant"] > 0 +tbl.instant > 0 --- - true ... -tbl["time"] > 0 +tbl.time > 0 --- - true ... diff --git a/test/app/fiber.test.lua b/test/app/fiber.test.lua index 38b85d554..33ebe063f 100644 --- a/test/app/fiber.test.lua +++ b/test/app/fiber.test.lua @@ -634,6 +634,17 @@ sum = 0 -- gh-2694 fiber.top() fiber.top_enable() +-- Check that a number is finite. +-- Lua doesn't have this, sorry. +function finite(num)\ + return type(num) == 'number' and num < math.huge and\ + num > -math.huge and tostring(num) ~= 'nan'\ +end + +-- Wait till a full event loop iteration passes, so that +-- top() contains meaningful results. +while not finite(fiber.top().cpu["1/sched"].instant) do fiber.yield() end + a = fiber.top() type(a) -- scheduler is present in fiber.top() @@ -652,19 +663,23 @@ for k, v in pairs(a) do\ sum_avg = sum_avg + v["average"]\ end -sum_inst +sum_inst > 99 and sum_inst < 101 or sum_inst -- not exact due to accumulated integer division errors sum_avg > 99 and sum_avg < 101 or sum_avg tbl = nil f = fiber.new(function()\ - for i = 1,1000 do end\ - fiber.yield()\ - tbl = fiber.top().cpu[fiber.self().id()..'/'..fiber.self().name()]\ + local fiber_key = fiber.self().id()..'/'..fiber.self().name()\ + tbl = fiber.top().cpu[fiber_key]\ + while tbl.time == 0 do\ + for i = 1,1000 do end\ + fiber.yield()\ + tbl = fiber.top().cpu[fiber_key]\ + end\ end) -while f:status() ~= 'dead' do fiber.sleep(0.01) end -tbl["average"] > 0 -tbl["instant"] > 0 -tbl["time"] > 0 +while f:status() ~= 'dead' do fiber.yield() end +tbl.average > 0 +tbl.instant > 0 +tbl.time > 0 fiber.top_disable() fiber.top() -- 2.21.0 (Apple Git-122)