diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | base/base.gypi | 10 | ||||
-rw-r--r-- | base/base_paths_linux.cc | 4 | ||||
-rw-r--r-- | base/basictypes.h | 4 | ||||
-rw-r--r-- | base/logging.cc | 5 | ||||
-rw-r--r-- | base/process_util.h | 6 | ||||
-rw-r--r-- | base/process_util_openbsd.cc | 331 | ||||
-rw-r--r-- | base/process_util_unittest.cc | 2 | ||||
-rw-r--r-- | base/sys_info_openbsd.cc | 13 | ||||
-rw-r--r-- | base/threading/platform_thread_posix.cc | 5 | ||||
-rw-r--r-- | build/common.gypi | 4 | ||||
-rwxr-xr-x | tools/clang/scripts/update.sh | 2 |
12 files changed, 372 insertions, 15 deletions
@@ -131,3 +131,4 @@ Robert Goldberg <goldberg@adobe.com> Don Woodward <woodward@adobe.com> Naveen Bobbili <naveenbobbili@motorola.com> Vamshikrishna Yellenki <vamshi@motorola.com> +Robert Nagy <robert@openbsd.org> diff --git a/base/base.gypi b/base/base.gypi index 0cfd03f..5223583 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -218,6 +218,7 @@ 'process_util.h', 'process_util_linux.cc', 'process_util_mac.mm', + 'process_util_openbsd.cc', 'process_util_posix.cc', 'process_util_win.cc', 'process_win.cc', @@ -494,6 +495,12 @@ 'files/file_path_watcher_stub.cc', ], }], + [ 'OS == "openbsd"', { + 'sources/': [ + ['include', '^base_paths_linux\\.cc$'], + ['include', '^sys_string_conversions_linux\\.cc$'], + ], + }], ], }], ], @@ -590,6 +597,9 @@ ], }], [ 'OS == "freebsd" or OS == "openbsd"', { + 'include_dirs': [ + '/usr/local/include', + ], 'link_settings': { 'libraries': [ '-L/usr/local/lib -lexecinfo', diff --git a/base/base_paths_linux.cc b/base/base_paths_linux.cc index 9f940cb..b082eb3 100644 --- a/base/base_paths_linux.cc +++ b/base/base_paths_linux.cc @@ -66,6 +66,10 @@ bool PathProviderPosix(int key, FilePath* result) { } *result = FilePath(bin_dir); return true; +#elif defined(OS_OPENBSD) + // There is currently no way to get the executable path on OpenBSD + *result = FilePath("/usr/local/chrome/chrome"); + return true; #endif } case base::DIR_SOURCE_ROOT: { diff --git a/base/basictypes.h b/base/basictypes.h index 7e34d4f..8bf4f78 100644 --- a/base/basictypes.h +++ b/base/basictypes.h @@ -32,7 +32,7 @@ typedef int int32; // // On Mac OS X, |long long| is used for 64-bit types for compatibility with // <inttypes.h> format macros even in the LP64 model. -#if defined(__LP64__) && !defined(OS_MACOSX) +#if defined(__LP64__) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) typedef long int64; #else typedef long long int64; @@ -54,7 +54,7 @@ typedef unsigned int uint32; #endif // See the comment above about NSPR and 64-bit. -#if defined(__LP64__) && !defined(OS_MACOSX) +#if defined(__LP64__) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) typedef unsigned long uint64; #else typedef unsigned long long uint64; diff --git a/base/logging.cc b/base/logging.cc index 2bf4dff..27754af 100644 --- a/base/logging.cc +++ b/base/logging.cc @@ -134,11 +134,10 @@ int32 CurrentThreadId() { return syscall(__NR_gettid); #elif defined(OS_ANDROID) return gettid(); -#elif defined(OS_FREEBSD) - // TODO(BSD): find a better thread ID - return reinterpret_cast<int64>(pthread_self()); #elif defined(OS_NACL) return pthread_self(); +#elif defined(OS_POSIX) + return reinterpret_cast<int64>(pthread_self()); #endif } diff --git a/base/process_util.h b/base/process_util.h index 4cd1da3..b4e4fc0 100644 --- a/base/process_util.h +++ b/base/process_util.h @@ -14,14 +14,16 @@ #if defined(OS_WIN) #include <windows.h> #include <tlhelp32.h> -#elif defined(OS_MACOSX) +#elif defined(OS_MACOSX) || defined(OS_OPENBSD) // kinfo_proc is defined in <sys/sysctl.h>, but this forward declaration // is sufficient for the vector<kinfo_proc> below. struct kinfo_proc; // malloc_zone_t is defined in <malloc/malloc.h>, but this forward declaration // is sufficient for GetPurgeableZone() below. typedef struct _malloc_zone_t malloc_zone_t; +#if !defined(OS_OPENBSD) #include <mach/mach.h> +#endif #elif defined(OS_POSIX) #include <dirent.h> #include <limits.h> @@ -526,7 +528,7 @@ class BASE_EXPORT ProcessIterator { #if defined(OS_WIN) HANDLE snapshot_; bool started_iteration_; -#elif defined(OS_MACOSX) +#elif defined(OS_MACOSX) || defined(OS_OPENBSD) std::vector<kinfo_proc> kinfo_procs_; size_t index_of_kinfo_proc_; #elif defined(OS_POSIX) diff --git a/base/process_util_openbsd.cc b/base/process_util_openbsd.cc new file mode 100644 index 0000000..b442e93 --- /dev/null +++ b/base/process_util_openbsd.cc @@ -0,0 +1,331 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/process_util.h" + +#include <ctype.h> +#include <dirent.h> +#include <dlfcn.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/user.h> +#include <time.h> +#include <unistd.h> + +#include "base/file_util.h" +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "base/string_split.h" +#include "base/string_tokenizer.h" +#include "base/string_util.h" +#include "base/sys_info.h" +#include "base/threading/thread_restrictions.h" + +namespace base { + +ProcessId GetParentProcessId(ProcessHandle process) { + struct kinfo_proc info; + size_t length; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process, + sizeof(struct kinfo_proc), 0 }; + + if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) + return -1; + + mib[5] = (length / sizeof(struct kinfo_proc)); + + if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) + return -1; + + return info.p_ppid; +} + +FilePath GetProcessExecutablePath(ProcessHandle process) { + return FilePath(std::string("/usr/local/chrome/chrome")); +} + +ProcessIterator::ProcessIterator(const ProcessFilter* filter) + : index_of_kinfo_proc_(), + filter_(filter) { + + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_UID, getuid(), + sizeof(struct kinfo_proc), 0 }; + + bool done = false; + int try_num = 1; + const int max_tries = 10; + + do { + size_t len = 0; + if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) { + LOG(ERROR) << "failed to get the size needed for the process list"; + kinfo_procs_.resize(0); + done = true; + } else { + size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc); + // Leave some spare room for process table growth (more could show up + // between when we check and now) + num_of_kinfo_proc += 16; + kinfo_procs_.resize(num_of_kinfo_proc); + len = num_of_kinfo_proc * sizeof(struct kinfo_proc); + if (sysctl(mib, arraysize(mib), &kinfo_procs_[0], &len, NULL, 0) < 0) { + // If we get a mem error, it just means we need a bigger buffer, so + // loop around again. Anything else is a real error and give up. + if (errno != ENOMEM) { + LOG(ERROR) << "failed to get the process list"; + kinfo_procs_.resize(0); + done = true; + } + } else { + // Got the list, just make sure we're sized exactly right + size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc); + kinfo_procs_.resize(num_of_kinfo_proc); + done = true; + } + } + } while (!done && (try_num++ < max_tries)); + + if (!done) { + LOG(ERROR) << "failed to collect the process list in a few tries"; + kinfo_procs_.resize(0); + } +} + +ProcessIterator::~ProcessIterator() { +} + +bool ProcessIterator::CheckForNextProcess() { + std::string data; + for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++index_of_kinfo_proc_) { + kinfo_proc& kinfo = kinfo_procs_[index_of_kinfo_proc_]; + + // Skip processes just awaiting collection + if ((kinfo.p_pid > 0) && (kinfo.p_stat == SZOMB)) + continue; + + int mib[] = { CTL_KERN, KERN_PROC_ARGS, kinfo.p_pid }; + + // Find out what size buffer we need. + size_t data_len = 0; + if (sysctl(mib, arraysize(mib), NULL, &data_len, NULL, 0) < 0) { + DVPLOG(1) << "failed to figure out the buffer size for a commandline"; + continue; + } + + data.resize(data_len); + if (sysctl(mib, arraysize(mib), &data[0], &data_len, NULL, 0) < 0) { + DVPLOG(1) << "failed to fetch a commandline"; + continue; + } + + // |data| contains all the command line parameters of the process, separated + // by blocks of one or more null characters. We tokenize |data| into a + // vector of strings using '\0' as a delimiter and populate + // |entry_.cmd_line_args_|. + std::string delimiters; + delimiters.push_back('\0'); + Tokenize(data, delimiters, &entry_.cmd_line_args_); + + // |data| starts with the full executable path followed by a null character. + // We search for the first instance of '\0' and extract everything before it + // to populate |entry_.exe_file_|. + size_t exec_name_end = data.find('\0'); + if (exec_name_end == std::string::npos) { + LOG(ERROR) << "command line data didn't match expected format"; + continue; + } + + entry_.pid_ = kinfo.p_pid; + entry_.ppid_ = kinfo.p_ppid; + entry_.gid_ = kinfo.p__pgid; + size_t last_slash = data.rfind('/', exec_name_end); + if (last_slash == std::string::npos) + entry_.exe_file_.assign(data, 0, exec_name_end); + else + entry_.exe_file_.assign(data, last_slash + 1, + exec_name_end - last_slash - 1); + // Start w/ the next entry next time through + ++index_of_kinfo_proc_; + // Done + return true; + } + return false; +} + +bool NamedProcessIterator::IncludeEntry() { + return (executable_name_ == entry().exe_file() && + ProcessIterator::IncludeEntry()); +} + + +ProcessMetrics::ProcessMetrics(ProcessHandle process) + : process_(process), + last_time_(0), + last_system_time_(0), + last_cpu_(0) { + + processor_count_ = base::SysInfo::NumberOfProcessors(); +} + +// static +ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) { + return new ProcessMetrics(process); +} + +size_t ProcessMetrics::GetPagefileUsage() const { + struct kinfo_proc info; + size_t length; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_, + sizeof(struct kinfo_proc), 0 }; + + if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) + return -1; + + mib[5] = (length / sizeof(struct kinfo_proc)); + + if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) + return -1; + + return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize); +} + +size_t ProcessMetrics::GetPeakPagefileUsage() const { + + return 0; +} + +size_t ProcessMetrics::GetWorkingSetSize() const { + struct kinfo_proc info; + size_t length; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_, + sizeof(struct kinfo_proc), 0 }; + + if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) + return -1; + + mib[5] = (length / sizeof(struct kinfo_proc)); + + if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) + return -1; + + return info.p_vm_rssize * getpagesize(); +} + +size_t ProcessMetrics::GetPeakWorkingSetSize() const { + + return 0; +} + +bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes, + size_t* shared_bytes) { + WorkingSetKBytes ws_usage; + + if (!GetWorkingSetKBytes(&ws_usage)) + return false; + + if (private_bytes) + *private_bytes = ws_usage.priv << 10; + + if (shared_bytes) + *shared_bytes = ws_usage.shared * 1024; + + return true; +} + +bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { +// TODO(bapt) be sure we can't be precise + size_t priv = GetWorkingSetSize(); + if (!priv) + return false; + ws_usage->priv = priv / 1024; + ws_usage->shareable = 0; + ws_usage->shared = 0; + + return true; +} + +bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { + return false; +} + +static int GetProcessCPU(pid_t pid) { + struct kinfo_proc info; + size_t length; + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid, + sizeof(struct kinfo_proc), 0 }; + + if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0) + return -1; + + mib[5] = (length / sizeof(struct kinfo_proc)); + + if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0) + return 0; + + return info.p_pctcpu; +} + +double ProcessMetrics::GetCPUUsage() { + struct timeval now; + + int retval = gettimeofday(&now, NULL); + if (retval) + return 0; + + int64 time = TimeValToMicroseconds(now); + + if (last_time_ == 0) { + // First call, just set the last values. + last_time_ = time; + last_cpu_ = GetProcessCPU(process_); + return 0; + } + + int64 time_delta = time - last_time_; + DCHECK_NE(time_delta, 0); + + if (time_delta == 0) + return 0; + + int cpu = GetProcessCPU(process_); + + last_time_ = time; + last_cpu_ = cpu; + + double percentage = static_cast<double>((cpu * 100.0) / FSCALE); + + return percentage; +} + +size_t GetSystemCommitCharge() { + int mib[] = { CTL_VM, VM_METER }; + int pagesize; + struct vmtotal vmtotal; + unsigned long mem_total, mem_free, mem_inactive; + size_t len = sizeof(vmtotal); + + if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0) + return 0; + + mem_total = vmtotal.t_vm; + mem_free = vmtotal.t_free; + mem_inactive = vmtotal.t_vm - vmtotal.t_avm; + + pagesize = getpagesize(); + + return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize); +} + +void EnableTerminationOnOutOfMemory() { +} + +void EnableTerminationOnHeapCorruption() { +} + +} // namespace base diff --git a/base/process_util_unittest.cc b/base/process_util_unittest.cc index 08a1fb2..5f75b2e 100644 --- a/base/process_util_unittest.cc +++ b/base/process_util_unittest.cc @@ -33,8 +33,6 @@ #include <signal.h> #include <sys/resource.h> #include <sys/socket.h> -#endif -#if defined(OS_ANDROID) #include <sys/wait.h> #endif #if defined(OS_WIN) diff --git a/base/sys_info_openbsd.cc b/base/sys_info_openbsd.cc index 8877222..2d1b390 100644 --- a/base/sys_info_openbsd.cc +++ b/base/sys_info_openbsd.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -22,4 +22,15 @@ int SysInfo::NumberOfProcessors() { return ncpu; } +int64 SysInfo::AmountOfPhysicalMemory() { + long pages = sysconf(_SC_PHYS_PAGES); + long page_size = sysconf(_SC_PAGESIZE); + if (pages == -1 || page_size == -1) { + NOTREACHED(); + return 0; + } + + return static_cast<int64>(pages) * page_size; +} + } // namespace base diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc index ee9b1b1..d1fb7bb 100644 --- a/base/threading/platform_thread_posix.cc +++ b/base/threading/platform_thread_posix.cc @@ -132,11 +132,10 @@ PlatformThreadId PlatformThread::CurrentId() { return syscall(__NR_gettid); #elif defined(OS_ANDROID) return gettid(); -#elif defined(OS_FREEBSD) - // TODO(BSD): find a better thread ID - return reinterpret_cast<int64>(pthread_self()); #elif defined(OS_NACL) || defined(OS_SOLARIS) return pthread_self(); +#elif defined(OS_POSIX) + return reinterpret_cast<int64>(pthread_self()); #endif } diff --git a/build/common.gypi b/build/common.gypi index 0fb69bb..7635514e 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -1138,13 +1138,15 @@ '-Wsign-compare', ] }], - [ 'os_posix==1 and OS!="mac" and chromeos==0', { + [ 'os_posix==1 and OS!="mac" and OS!="openbsd" and chromeos==0', { 'cflags': [ # Don't warn about ignoring the return value from e.g. close(). # This is off by default in some gccs but on by default in others. # Currently this option is not set for Chrome OS build because # the current version of gcc (4.3.4) used for building Chrome in # Chrome OS chroot doesn't support this option. + # OpenBSD does not support this option either, since it's using + # gcc 4.2.1, which does not have this flag yet. # TODO(mazda): remove the conditional for Chrome OS when gcc # version is upgraded. '-Wno-unused-result', diff --git a/tools/clang/scripts/update.sh b/tools/clang/scripts/update.sh index 47419b3..b14d8a8 100755 --- a/tools/clang/scripts/update.sh +++ b/tools/clang/scripts/update.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. |