From 999e827ed1d9b5c966af2fc7480e57d2b60b7b09 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Tue, 26 Feb 2013 11:05:51 +0100 Subject: [observer] Improve measurement of CPU utilization in etop Now using scheduler_wall_time instead of runtime/wall_clock to get cpu utilization. The old version could give CPU utilization far beyond 100%. Also, a bug which sometimes gave a badarith when calculating the CPU utilization is corrected. --- lib/runtime_tools/include/observer_backend.hrl | 23 ++++++++++---------- lib/runtime_tools/src/observer_backend.erl | 30 +++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 14 deletions(-) (limited to 'lib/runtime_tools') diff --git a/lib/runtime_tools/include/observer_backend.hrl b/lib/runtime_tools/include/observer_backend.hrl index 4be9baca5b..91647a4468 100644 --- a/lib/runtime_tools/include/observer_backend.hrl +++ b/lib/runtime_tools/include/observer_backend.hrl @@ -1,26 +1,27 @@ -%% ``The contents of this file are subject to the Erlang Public License, +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be -%% retrieved via the world wide web at http://www.erlang.org/. -%% +%% retrieved online at http://www.erlang.org/. +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% -%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. -%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings -%% AB. All Rights Reserved.'' -%% -%% $Id$ +%% +%% %CopyrightEnd% %% -record(etop_info, {now = {0, 0, 0}, n_procs = 0, - wall_clock = {0, 0}, - runtime = {0, 0}, + wall_clock, + runtime, run_queue = 0, alloc_areas = [], memi = [{total, 0}, diff --git a/lib/runtime_tools/src/observer_backend.erl b/lib/runtime_tools/src/observer_backend.erl index e8c9b50c33..d1d291d5cb 100644 --- a/lib/runtime_tools/src/observer_backend.erl +++ b/lib/runtime_tools/src/observer_backend.erl @@ -217,15 +217,39 @@ fetch_stats_loop(Parent, Time) -> %% etop backend %% etop_collect(Collector) -> + %% If this is the first time and the scheduler_wall_time flag is + %% false, SchedulerWallTime will be 'undefined' (and show 0 cpu + %% utilization in etop). Next time the flag will be true and then + %% there will be a measurement. + SchedulerWallTime = erlang:statistics(scheduler_wall_time), + + %% Turn off the flag while collecting data per process etc. + case erlang:system_flag(scheduler_wall_time,false) of + false -> + %% First time and the flag was false - start a monitoring + %% process to set the flag back to false when etop is stopped. + spawn(fun() -> flag_holder_proc(Collector) end); + _ -> + ok + end, + ProcInfo = etop_collect(processes(), []), + Collector ! {self(),#etop_info{now = now(), n_procs = length(ProcInfo), run_queue = erlang:statistics(run_queue), - wall_clock = erlang:statistics(wall_clock), - runtime = erlang:statistics(runtime), + runtime = SchedulerWallTime, memi = etop_memi(), procinfo = ProcInfo - }}. + }}, + erlang:system_flag(scheduler_wall_time,true). + +flag_holder_proc(Collector) -> + Ref = erlang:monitor(process,Collector), + receive + {'DOWN',Ref,_,_,_} -> + erlang:system_flag(scheduler_wall_time,false) + end. etop_memi() -> try -- cgit v1.2.3