diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-19 01:31:03 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-19 01:31:03 +0000 |
commit | 0d525036512529fc73287726ac65649040672f86 (patch) | |
tree | c7228937ed591491d541b76aee909ee3090fb1db | |
parent | 27f2b6626e1c0e71d8b8e5d20e017beee762d7d6 (diff) | |
download | chromium_src-0d525036512529fc73287726ac65649040672f86.zip chromium_src-0d525036512529fc73287726ac65649040672f86.tar.gz chromium_src-0d525036512529fc73287726ac65649040672f86.tar.bz2 |
Revert 34994, maybe it regressed startup perf - Fix cpu/memory measurements on OS X.
Right now, this only works for the current process; support for child processes will be added in a later CL.
BUG=13156,25454
TEST=Hook up task manager (connect menu item to commandDispatch:, give it the right tag). Stats for the browser process should now be right, and %cpu should be 0 (for now) for all other processes.
Review URL: http://codereview.chromium.org/500118
TBR=thakis@chromium.org
Review URL: http://codereview.chromium.org/504068
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35025 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/process_util.h | 32 | ||||
-rw-r--r-- | base/process_util_mac.mm | 125 | ||||
-rw-r--r-- | base/process_util_posix.cc | 67 | ||||
-rw-r--r-- | base/trace_event.cc | 7 | ||||
-rw-r--r-- | chrome/browser/safe_browsing/safe_browsing_database_unittest.cc | 5 | ||||
-rw-r--r-- | chrome/browser/task_manager.cc | 13 | ||||
-rw-r--r-- | chrome/common/mach_ipc_mac.h | 5 | ||||
-rw-r--r-- | chrome/common/mach_ipc_mac.mm | 8 | ||||
-rw-r--r-- | chrome/test/chrome_process_util.h | 7 | ||||
-rw-r--r-- | webkit/glue/webkitclient_impl.cc | 7 |
10 files changed, 64 insertions, 212 deletions
diff --git a/base/process_util.h b/base/process_util.h index 2bb5396..1122de7 100644 --- a/base/process_util.h +++ b/base/process_util.h @@ -317,11 +317,6 @@ class NamedProcessIterator { // priv: Pages mapped only by this process // shared: PSS or 0 if the kernel doesn't support this // shareable: 0 -// -// On OS X: TODO(thakis): Revise. -// priv: Memory. -// shared: 0 -// shareable: 0 struct WorkingSetKBytes { WorkingSetKBytes() : priv(0), shareable(0), shared(0) {} size_t priv; @@ -364,23 +359,7 @@ class ProcessMetrics { public: // Creates a ProcessMetrics for the specified process. // The caller owns the returned object. -#if !defined(OS_MACOSX) static ProcessMetrics* CreateProcessMetrics(ProcessHandle process); -#else - class PortProvider { - public: - // Should return the mach task for |process| if possible, or else 0. Only - // processes that this returns tasks for will have metrics on OS X (except - // for the current process, which always gets metrics). - virtual mach_port_t TaskForPid(ProcessHandle process) const = 0; - }; - - // The port provider needs to outlive the ProcessMetrics object returned by - // this function. If NULL is passed as provider, the returned object - // only returns valid metrics if |process| is the current process. - static ProcessMetrics* CreateProcessMetrics(ProcessHandle process, - PortProvider* port_provider); -#endif ~ProcessMetrics(); @@ -428,11 +407,7 @@ class ProcessMetrics { bool GetIOCounters(IoCounters* io_counters) const; private: -#if !defined(OS_MACOSX) explicit ProcessMetrics(ProcessHandle process); -#else - ProcessMetrics(ProcessHandle process, PortProvider* port_provider); -#endif ProcessHandle process_; @@ -448,13 +423,6 @@ class ProcessMetrics { int last_cpu_; #endif -#if defined(OS_MACOSX) - // Queries the port provider if it's set. - mach_port_t TaskForPid(ProcessHandle process) const; - - PortProvider* port_provider_; -#endif - DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics); }; diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm index dd4dc37..91944e8 100644 --- a/base/process_util_mac.mm +++ b/base/process_util_mac.mm @@ -182,46 +182,23 @@ bool NamedProcessIterator::IncludeEntry() { // ------------------------------------------------------------------------ // NOTE: about ProcessMetrics // -// Getting a mach task from a pid for another process requires permissions in -// general, so there doesn't really seem to be a way to do these (and spinning -// up ps to fetch each stats seems dangerous to put in a base api for anyone to -// call). Child processes ipc their port, so return something if available, -// otherwise return 0. +// Mac doesn't have /proc, and getting a mach task from a pid for another +// process requires permissions, so there doesn't really seem to be a way +// to do these (and spinning up ps to fetch each stats seems dangerous to +// put in a base api for anyone to call. // bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { return false; } - -static bool GetTaskInfo(mach_port_t task, task_basic_info_64* task_info_data) { - if (!task) - return false; - mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT; - kern_return_t kr = task_info(task, - TASK_BASIC_INFO_64, - reinterpret_cast<task_info_t>(task_info_data), - &count); - // Most likely cause for failure: |task| is a zombie. - return kr == KERN_SUCCESS; -} - size_t ProcessMetrics::GetPagefileUsage() const { - task_basic_info_64 task_info_data; - if (!GetTaskInfo(TaskForPid(process_), &task_info_data)) - return 0; - return task_info_data.virtual_size; + return 0; } - size_t ProcessMetrics::GetPeakPagefileUsage() const { return 0; } - size_t ProcessMetrics::GetWorkingSetSize() const { - task_basic_info_64 task_info_data; - if (!GetTaskInfo(TaskForPid(process_), &task_info_data)) - return 0; - return task_info_data.resident_size; + return 0; } - size_t ProcessMetrics::GetPeakWorkingSetSize() const { return 0; } @@ -234,95 +211,7 @@ void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { } bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { - size_t priv = GetWorkingSetSize(); - if (!priv) - return false; - ws_usage->priv = priv / 1024; - ws_usage->shareable = 0; - ws_usage->shared = 0; - return true; -} - -#define TIME_VALUE_TO_TIMEVAL(a, r) do { \ - (r)->tv_sec = (a)->seconds; \ - (r)->tv_usec = (a)->microseconds; \ -} while (0) - -int ProcessMetrics::GetCPUUsage() { - mach_port_t task = TaskForPid(process_); - if (!task) - return 0; - - kern_return_t kr; - - // TODO(thakis): Libtop doesn't use thread info. How can they get away - // without it? - task_thread_times_info thread_info_data; - mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT; - kr = task_info(task, - TASK_THREAD_TIMES_INFO, - reinterpret_cast<task_info_t>(&thread_info_data), - &thread_info_count); - if (kr != KERN_SUCCESS) { - // Most likely cause: |task| is a zombie. - return 0; - } - - task_basic_info_64 task_info_data; - if (!GetTaskInfo(task, &task_info_data)) - return 0; - - /* Set total_time. */ - // thread info contains live time... - struct timeval user_timeval, system_timeval, task_timeval; - TIME_VALUE_TO_TIMEVAL(&thread_info_data.user_time, &user_timeval); - TIME_VALUE_TO_TIMEVAL(&thread_info_data.system_time, &system_timeval); - timeradd(&user_timeval, &system_timeval, &task_timeval); - - // ... task info contains terminated time. - TIME_VALUE_TO_TIMEVAL(&task_info_data.user_time, &user_timeval); - TIME_VALUE_TO_TIMEVAL(&task_info_data.system_time, &system_timeval); - timeradd(&user_timeval, &task_timeval, &task_timeval); - timeradd(&system_timeval, &task_timeval, &task_timeval); - - struct timeval now; - int retval = gettimeofday(&now, NULL); - if (retval) - return 0; - - int64 time = TimeValToMicroseconds(now); - int64 task_time = TimeValToMicroseconds(task_timeval); - - if ((last_system_time_ == 0) || (last_time_ == 0)) { - // First call, just set the last values. - last_system_time_ = task_time; - last_time_ = time; - return 0; - } - - int64 system_time_delta = task_time - last_system_time_; - int64 time_delta = time - last_time_; - DCHECK(time_delta != 0); - if (time_delta == 0) - return 0; - - // We add time_delta / 2 so the result is rounded. - int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) / - (time_delta)); - - last_system_time_ = task_time; - last_time_ = time; - - return cpu; -} - -mach_port_t ProcessMetrics::TaskForPid(ProcessHandle process) const { - mach_port_t task = 0; - if (port_provider_) - task = port_provider_->TaskForPid(process_); - if (!task && process_ == getpid()) - task = mach_task_self(); - return task; + return false; } // ------------------------------------------------------------------------ diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc index 16469db..4392c7b 100644 --- a/base/process_util_posix.cc +++ b/base/process_util_posix.cc @@ -360,36 +360,20 @@ bool LaunchApp(const CommandLine& cl, return LaunchApp(cl.argv(), no_files, wait, process_handle); } -#if !defined(OS_MACOSX) -ProcessMetrics::ProcessMetrics(ProcessHandle process) -#else -ProcessMetrics::ProcessMetrics(ProcessHandle process, - ProcessMetrics::PortProvider* port_provider) -#endif - : process_(process), - last_time_(0), - last_system_time_(0) +ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process), + last_time_(0), + last_system_time_(0) #if defined(OS_LINUX) - , last_cpu_(0) -#elif defined (OS_MACOSX) - , port_provider_(port_provider) + , last_cpu_(0) #endif { processor_count_ = base::SysInfo::NumberOfProcessors(); } // static -#if !defined(OS_MACOSX) ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) { return new ProcessMetrics(process); } -#else -ProcessMetrics* ProcessMetrics::CreateProcessMetrics( - ProcessHandle process, - ProcessMetrics::PortProvider* port_provider) { - return new ProcessMetrics(process, port_provider); -} -#endif ProcessMetrics::~ProcessMetrics() { } @@ -510,6 +494,49 @@ int64 TimeValToMicroseconds(const struct timeval& tv) { return tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec; } +#if defined(OS_MACOSX) +// TODO(port): this function only returns the *current* CPU's usage; +// we want to return this->process_'s CPU usage. +int ProcessMetrics::GetCPUUsage() { + struct timeval now; + struct rusage usage; + + int retval = gettimeofday(&now, NULL); + if (retval) + return 0; + retval = getrusage(RUSAGE_SELF, &usage); + if (retval) + return 0; + + int64 system_time = (TimeValToMicroseconds(usage.ru_stime) + + TimeValToMicroseconds(usage.ru_utime)) / + processor_count_; + int64 time = TimeValToMicroseconds(now); + + if ((last_system_time_ == 0) || (last_time_ == 0)) { + // First call, just set the last values. + last_system_time_ = system_time; + last_time_ = time; + return 0; + } + + int64 system_time_delta = system_time - last_system_time_; + int64 time_delta = time - last_time_; + DCHECK(time_delta != 0); + if (time_delta == 0) + return 0; + + // We add time_delta / 2 so the result is rounded. + int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) / + time_delta); + + last_system_time_ = system_time; + last_time_ = time; + + return cpu; +} +#endif + // Executes the application specified by |cl| and wait for it to exit. Stores // the output (stdout) in |output|. If |do_search_path| is set, it searches the // path for the application; in that case, |envp| must be null, and it will use diff --git a/base/trace_event.cc b/base/trace_event.cc index ff834ea..13c0c2c 100644 --- a/base/trace_event.cc +++ b/base/trace_event.cc @@ -29,14 +29,7 @@ static const FilePath::CharType* kLogFileName = TraceLog::TraceLog() : enabled_(false), log_file_(NULL) { base::ProcessHandle proc = base::GetCurrentProcessHandle(); -#if !defined(OS_MACOSX) process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(proc)); -#else - // The default port provider is sufficient to get data for the current - // process. - process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(proc, - NULL)); -#endif } TraceLog::~TraceLog() { diff --git a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc index 30f9de4..3d244c0 100644 --- a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc @@ -1078,12 +1078,7 @@ void PeformUpdate(const std::wstring& initial_db, Time before_time = Time::Now(); base::ProcessHandle handle = base::Process::Current().handle(); scoped_ptr<base::ProcessMetrics> metric( -#if !defined(OS_MACOSX) base::ProcessMetrics::CreateProcessMetrics(handle)); -#else - // Getting stats only for the current process is enough, so NULL is fine. - base::ProcessMetrics::CreateProcessMetrics(handle, NULL)); -#endif CHECK(metric->GetIOCounters(&before)); std::vector<SBListChunkRanges> lists; diff --git a/chrome/browser/task_manager.cc b/chrome/browser/task_manager.cc index edd7b37..43952a5 100644 --- a/chrome/browser/task_manager.cc +++ b/chrome/browser/task_manager.cc @@ -533,14 +533,7 @@ void TaskManagerModel::AddResource(TaskManager::Resource* resource) { // Create the ProcessMetrics for this process if needed (not in map). if (metrics_map_.find(process) == metrics_map_.end()) { base::ProcessMetrics* pm = -#if !defined(OS_MACOSX) base::ProcessMetrics::CreateProcessMetrics(process); -#else - // TODO(thakis): Write a port provider that knows the task ports of - // child processes. - base::ProcessMetrics::CreateProcessMetrics(process, NULL); -#endif - metrics_map_[process] = pm; } @@ -777,12 +770,12 @@ void TaskManagerModel::OnJobRemoved(URLRequestJob* job) { } void TaskManagerModel::OnJobDone(URLRequestJob* job, - const URLRequestStatus& status) { + const URLRequestStatus& status) { } void TaskManagerModel::OnJobRedirect(URLRequestJob* job, - const GURL& location, - int status_code) { + const GURL& location, + int status_code) { } void TaskManagerModel::OnBytesRead(URLRequestJob* job, int byte_count) { diff --git a/chrome/common/mach_ipc_mac.h b/chrome/common/mach_ipc_mac.h index 42b9c65..8c345dd 100644 --- a/chrome/common/mach_ipc_mac.h +++ b/chrome/common/mach_ipc_mac.h @@ -167,9 +167,8 @@ class MachMessage { bool AddDescriptor(const MachMsgPortDescriptor &desc); int GetDescriptorCount() const { - return storage_->body.msgh_descriptor_count; - } - + return storage_->body.msgh_descriptor_count; + } MachMsgPortDescriptor *GetDescriptor(int n); // Convenience method which gets the mach port described by the descriptor diff --git a/chrome/common/mach_ipc_mac.mm b/chrome/common/mach_ipc_mac.mm index 7693d9a..3c95ef6 100644 --- a/chrome/common/mach_ipc_mac.mm +++ b/chrome/common/mach_ipc_mac.mm @@ -213,10 +213,10 @@ ReceivePort::ReceivePort() { if (init_result_ != KERN_SUCCESS) return; - init_result_ = mach_port_insert_right(current_task, - port_, - port_, - MACH_MSG_TYPE_MAKE_SEND); + init_result_ = mach_port_insert_right(current_task, + port_, + port_, + MACH_MSG_TYPE_MAKE_SEND); } //============================================================================== diff --git a/chrome/test/chrome_process_util.h b/chrome/test/chrome_process_util.h index 4fb1513..19a5446 100644 --- a/chrome/test/chrome_process_util.h +++ b/chrome/test/chrome_process_util.h @@ -57,12 +57,7 @@ class ChromeTestProcessMetrics { private: explicit ChromeTestProcessMetrics(base::ProcessHandle process) { - process_metrics_.reset( -#if !defined(OS_MACOSX) - base::ProcessMetrics::CreateProcessMetrics(process)); -#else - base::ProcessMetrics::CreateProcessMetrics(process, NULL)); -#endif + process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(process)); process_handle_ = process; } diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index c7673cf..340a28c 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -318,14 +318,7 @@ WebKit::WebString WebKitClientImpl::signedPublicKeyAndChallengeString( size_t WebKitClientImpl::memoryUsageMB() { using base::ProcessMetrics; static ProcessMetrics* process_metrics = -#if !defined(OS_MACOSX) ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle()); -#else - // The default port provider is sufficient to get data for the current - // process. - ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle(), - NULL); -#endif DCHECK(process_metrics); return process_metrics->GetPagefileUsage() >> 20; } |