mirror of
https://github.com/google/benchmark.git
synced 2024-12-29 14:00:16 +08:00
commit
65ed470c0f
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,10 +1,14 @@
|
|||||||
*.a
|
*.a
|
||||||
*.so
|
*.so
|
||||||
*.so.?*
|
*.so.?*
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
*.dylib
|
*.dylib
|
||||||
*.cmake
|
*.cmake
|
||||||
!/cmake/*.cmake
|
!/cmake/*.cmake
|
||||||
*~
|
*~
|
||||||
|
*.pyc
|
||||||
|
__pycache__
|
||||||
|
|
||||||
# cmake files.
|
# cmake files.
|
||||||
/Testing
|
/Testing
|
||||||
|
55
appveyor.yml
Normal file
55
appveyor.yml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
version: '{build}'
|
||||||
|
|
||||||
|
configuration:
|
||||||
|
- Static Debug
|
||||||
|
- Static Release
|
||||||
|
# - Shared Debug
|
||||||
|
# - Shared Release
|
||||||
|
|
||||||
|
platform:
|
||||||
|
- x86
|
||||||
|
- x64
|
||||||
|
|
||||||
|
environment:
|
||||||
|
matrix:
|
||||||
|
- compiler: gcc-4.9.2-posix
|
||||||
|
# - compiler: gcc-4.8.4-posix
|
||||||
|
# - compiler: msvc-12-seh
|
||||||
|
|
||||||
|
install:
|
||||||
|
# derive some extra information
|
||||||
|
- for /f "tokens=1-2" %%a in ("%configuration%") do (@set "linkage=%%a")
|
||||||
|
- for /f "tokens=1-2" %%a in ("%configuration%") do (@set "variant=%%b")
|
||||||
|
- if "%linkage%"=="Shared" (set shared=YES) else (set shared=NO)
|
||||||
|
- for /f "tokens=1-3 delims=-" %%a in ("%compiler%") do (@set "compiler_name=%%a")
|
||||||
|
- for /f "tokens=1-3 delims=-" %%a in ("%compiler%") do (@set "compiler_version=%%b")
|
||||||
|
- for /f "tokens=1-3 delims=-" %%a in ("%compiler%") do (@set "compiler_threading=%%c")
|
||||||
|
- if "%platform%"=="x64" (set arch=x86_64)
|
||||||
|
- if "%platform%"=="x86" (set arch=i686)
|
||||||
|
# download the specific version of MinGW
|
||||||
|
- if "%compiler_name%"=="gcc" (for /f %%a in ('python mingw.py --quiet --version "%compiler_version%" --arch "%arch%" --threading "%compiler_threading%" --location "C:\mingw-builds"') do @set "compiler_path=%%a")
|
||||||
|
|
||||||
|
before_build:
|
||||||
|
# Set up mingw commands
|
||||||
|
- if "%compiler_name%"=="gcc" (set "generator=MinGW Makefiles")
|
||||||
|
- if "%compiler_name%"=="gcc" (set "build=mingw32-make -j4")
|
||||||
|
- if "%compiler_name%"=="gcc" (set "test=mingw32-make CTEST_OUTPUT_ON_FAILURE=1 test")
|
||||||
|
# msvc specific commands
|
||||||
|
# TODO :)
|
||||||
|
# add the compiler path if needed
|
||||||
|
- if not "%compiler_path%"=="" (set "PATH=%PATH%;%compiler_path%")
|
||||||
|
# git bash conflicts with MinGW makefiles
|
||||||
|
- if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files (x86)\Git\bin=%")
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%variant%" "-DBENCHMARK_ENABLE_SHARED=%shared%"
|
||||||
|
- cmd /c "%build%"
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- cmd /c "%test%"
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- C:\mingw-builds
|
320
mingw.py
Normal file
320
mingw.py
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import errno
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
try:
|
||||||
|
import winreg
|
||||||
|
except ImportError:
|
||||||
|
import _winreg as winreg
|
||||||
|
try:
|
||||||
|
import urllib.request as request
|
||||||
|
except ImportError:
|
||||||
|
import urllib as request
|
||||||
|
try:
|
||||||
|
import urllib.parse as parse
|
||||||
|
except ImportError:
|
||||||
|
import urlparse as parse
|
||||||
|
|
||||||
|
class EmptyLogger(object):
|
||||||
|
'''
|
||||||
|
Provides an implementation that performs no logging
|
||||||
|
'''
|
||||||
|
def debug(self, *k, **kw):
|
||||||
|
pass
|
||||||
|
def info(self, *k, **kw):
|
||||||
|
pass
|
||||||
|
def warn(self, *k, **kw):
|
||||||
|
pass
|
||||||
|
def error(self, *k, **kw):
|
||||||
|
pass
|
||||||
|
def critical(self, *k, **kw):
|
||||||
|
pass
|
||||||
|
def setLevel(self, *k, **kw):
|
||||||
|
pass
|
||||||
|
|
||||||
|
urls = (
|
||||||
|
'http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20'
|
||||||
|
'targetting%20Win32/Personal%20Builds/mingw-builds/installer/'
|
||||||
|
'repository.txt',
|
||||||
|
'http://downloads.sourceforge.net/project/mingwbuilds/host-windows/'
|
||||||
|
'repository.txt'
|
||||||
|
)
|
||||||
|
'''
|
||||||
|
A list of mingw-build repositories
|
||||||
|
'''
|
||||||
|
|
||||||
|
def repository(urls = urls, log = EmptyLogger()):
|
||||||
|
'''
|
||||||
|
Downloads and parse mingw-build repository files and parses them
|
||||||
|
'''
|
||||||
|
log.info('getting mingw-builds repository')
|
||||||
|
versions = {}
|
||||||
|
re_sourceforge = re.compile(r'http://sourceforge.net/projects/([^/]+)/files')
|
||||||
|
re_sub = r'http://downloads.sourceforge.net/project/\1'
|
||||||
|
for url in urls:
|
||||||
|
log.debug(' - requesting: %s', url)
|
||||||
|
socket = request.urlopen(url)
|
||||||
|
repo = socket.read()
|
||||||
|
if not isinstance(repo, str):
|
||||||
|
repo = repo.decode();
|
||||||
|
socket.close()
|
||||||
|
for entry in repo.split('\n')[:-1]:
|
||||||
|
value = entry.split('|')
|
||||||
|
version = tuple([int(n) for n in value[0].strip().split('.')])
|
||||||
|
version = versions.setdefault(version, {})
|
||||||
|
arch = value[1].strip()
|
||||||
|
if arch == 'x32':
|
||||||
|
arch = 'i686'
|
||||||
|
elif arch == 'x64':
|
||||||
|
arch = 'x86_64'
|
||||||
|
arch = version.setdefault(arch, {})
|
||||||
|
threading = arch.setdefault(value[2].strip(), {})
|
||||||
|
exceptions = threading.setdefault(value[3].strip(), {})
|
||||||
|
revision = exceptions.setdefault(int(value[4].strip()[3:]),
|
||||||
|
re_sourceforge.sub(re_sub, value[5].strip()))
|
||||||
|
return versions
|
||||||
|
|
||||||
|
def find_in_path(file, path=None):
|
||||||
|
'''
|
||||||
|
Attempts to find an executable in the path
|
||||||
|
'''
|
||||||
|
if platform.system() == 'Windows':
|
||||||
|
file += '.exe'
|
||||||
|
if path is None:
|
||||||
|
path = os.environ.get('PATH', '')
|
||||||
|
if type(path) is type(''):
|
||||||
|
path = path.split(os.pathsep)
|
||||||
|
return list(filter(os.path.exists,
|
||||||
|
map(lambda dir, file=file: os.path.join(dir, file), path)))
|
||||||
|
|
||||||
|
def find_7zip(log = EmptyLogger()):
|
||||||
|
'''
|
||||||
|
Attempts to find 7zip for unpacking the mingw-build archives
|
||||||
|
'''
|
||||||
|
log.info('finding 7zip')
|
||||||
|
path = find_in_path('7z')
|
||||||
|
if not path:
|
||||||
|
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\7-Zip')
|
||||||
|
path, _ = winreg.QueryValueEx(key, 'Path')
|
||||||
|
path = [os.path.join(path, '7z.exe')]
|
||||||
|
log.debug('found \'%s\'', path[0])
|
||||||
|
return path[0]
|
||||||
|
|
||||||
|
find_7zip()
|
||||||
|
|
||||||
|
def unpack(archive, location, log = EmptyLogger()):
|
||||||
|
'''
|
||||||
|
Unpacks a mingw-builds archive
|
||||||
|
'''
|
||||||
|
sevenzip = find_7zip(log)
|
||||||
|
log.info('unpacking %s', os.path.basename(archive))
|
||||||
|
cmd = [sevenzip, 'x', archive, '-o' + location, '-y']
|
||||||
|
log.debug(' - %r', cmd)
|
||||||
|
with open(os.devnull, 'w') as devnull:
|
||||||
|
subprocess.check_call(cmd, stdout = devnull)
|
||||||
|
|
||||||
|
def download(url, location, log = EmptyLogger()):
|
||||||
|
'''
|
||||||
|
Downloads and unpacks a mingw-builds archive
|
||||||
|
'''
|
||||||
|
log.info('downloading MinGW')
|
||||||
|
log.debug(' - url: %s', url)
|
||||||
|
log.debug(' - location: %s', location)
|
||||||
|
|
||||||
|
re_content = re.compile(r'attachment;[ \t]*filename=(")?([^"]*)(")?[\r\n]*')
|
||||||
|
|
||||||
|
stream = request.urlopen(url)
|
||||||
|
try:
|
||||||
|
content = stream.getheader('Content-Disposition') or ''
|
||||||
|
except AttributeError:
|
||||||
|
content = stream.headers.getheader('Content-Disposition') or ''
|
||||||
|
matches = re_content.match(content)
|
||||||
|
if matches:
|
||||||
|
filename = matches.group(2)
|
||||||
|
else:
|
||||||
|
parsed = parse.urlparse(stream.geturl())
|
||||||
|
filename = os.path.basename(parsed.path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.makedirs(location)
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno == errno.EEXIST and os.path.isdir(location):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
archive = os.path.join(location, filename)
|
||||||
|
with open(archive, 'wb') as out:
|
||||||
|
while True:
|
||||||
|
buf = stream.read(1024)
|
||||||
|
if not buf:
|
||||||
|
break
|
||||||
|
out.write(buf)
|
||||||
|
unpack(archive, location, log = log)
|
||||||
|
os.remove(archive)
|
||||||
|
|
||||||
|
possible = os.path.join(location, 'mingw64')
|
||||||
|
if not os.path.exists(possible):
|
||||||
|
possible = os.path.join(location, 'mingw32')
|
||||||
|
if not os.path.exists(possible):
|
||||||
|
raise ValueError('Failed to find unpacked MinGW: ' + possible)
|
||||||
|
return possible
|
||||||
|
|
||||||
|
def root(location = None, arch = None, version = None, threading = None,
|
||||||
|
exceptions = None, revision = None, log = EmptyLogger()):
|
||||||
|
'''
|
||||||
|
Returns the root folder of a specific version of the mingw-builds variant
|
||||||
|
of gcc. Will download the compiler if needed
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Get the repository if we don't have all the information
|
||||||
|
if not (arch and version and threading and exceptions and revision):
|
||||||
|
versions = repository(log = log)
|
||||||
|
|
||||||
|
# Determine some defaults
|
||||||
|
version = version or max(versions.keys())
|
||||||
|
if not arch:
|
||||||
|
arch = platform.machine().lower()
|
||||||
|
if arch == 'x86':
|
||||||
|
arch = 'i686'
|
||||||
|
elif arch == 'amd64':
|
||||||
|
arch = 'x86_64'
|
||||||
|
if not threading:
|
||||||
|
keys = versions[version][arch].keys()
|
||||||
|
if 'posix' in keys:
|
||||||
|
threading = 'posix'
|
||||||
|
elif 'win32' in keys:
|
||||||
|
threading = 'win32'
|
||||||
|
else:
|
||||||
|
threading = keys[0]
|
||||||
|
if not exceptions:
|
||||||
|
keys = versions[version][arch][threading].keys()
|
||||||
|
if 'seh' in keys:
|
||||||
|
exceptions = 'seh'
|
||||||
|
elif 'sjlj' in keys:
|
||||||
|
exceptions = 'sjlj'
|
||||||
|
else:
|
||||||
|
exceptions = keys[0]
|
||||||
|
if revision == None:
|
||||||
|
revision = max(versions[version][arch][threading][exceptions].keys())
|
||||||
|
if not location:
|
||||||
|
location = os.path.join(tempfile.gettempdir(), 'mingw-builds')
|
||||||
|
|
||||||
|
# Get the download url
|
||||||
|
url = versions[version][arch][threading][exceptions][revision]
|
||||||
|
|
||||||
|
# Tell the user whatzzup
|
||||||
|
log.info('finding MinGW %s', '.'.join(str(v) for v in version))
|
||||||
|
log.debug(' - arch: %s', arch)
|
||||||
|
log.debug(' - threading: %s', threading)
|
||||||
|
log.debug(' - exceptions: %s', exceptions)
|
||||||
|
log.debug(' - revision: %s', revision)
|
||||||
|
log.debug(' - url: %s', url)
|
||||||
|
|
||||||
|
# Store each specific revision differently
|
||||||
|
slug = '{version}-{arch}-{threading}-{exceptions}-rev{revision}'
|
||||||
|
slug = slug.format(
|
||||||
|
version = '.'.join(str(v) for v in version),
|
||||||
|
arch = arch,
|
||||||
|
threading = threading,
|
||||||
|
exceptions = exceptions,
|
||||||
|
revision = revision
|
||||||
|
)
|
||||||
|
if arch == 'x86_64':
|
||||||
|
root_dir = os.path.join(location, slug, 'mingw64')
|
||||||
|
elif arch == 'i686':
|
||||||
|
root_dir = os.path.join(location, slug, 'mingw32')
|
||||||
|
else:
|
||||||
|
raise ValueError('Unknown MinGW arch: ' + arch)
|
||||||
|
|
||||||
|
# Download if needed
|
||||||
|
if not os.path.exists(root_dir):
|
||||||
|
downloaded = download(url, os.path.join(location, slug), log = log)
|
||||||
|
if downloaded != root_dir:
|
||||||
|
raise ValueError('The location of mingw did not match\n%s\n%s'
|
||||||
|
% (downloaded, root_dir))
|
||||||
|
|
||||||
|
return root_dir
|
||||||
|
|
||||||
|
def str2ver(string):
|
||||||
|
'''
|
||||||
|
Converts a version string into a tuple
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
version = tuple(int(v) for v in string.split('.'))
|
||||||
|
if len(version) is not 3:
|
||||||
|
raise ValueError()
|
||||||
|
except ValueError:
|
||||||
|
raise argparse.ArgumentTypeError(
|
||||||
|
'please provide a three digit version string')
|
||||||
|
return version
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''
|
||||||
|
Invoked when the script is run directly by the python interpreter
|
||||||
|
'''
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description = 'Downloads a specific version of MinGW',
|
||||||
|
formatter_class = argparse.ArgumentDefaultsHelpFormatter
|
||||||
|
)
|
||||||
|
parser.add_argument('--location',
|
||||||
|
help = 'the location to download the compiler to',
|
||||||
|
default = os.path.join(tempfile.gettempdir(), 'mingw-builds'))
|
||||||
|
parser.add_argument('--arch', required = True, choices = ['i686', 'x86_64'],
|
||||||
|
help = 'the target MinGW architecture string')
|
||||||
|
parser.add_argument('--version', type = str2ver,
|
||||||
|
help = 'the version of GCC to download')
|
||||||
|
parser.add_argument('--threading', choices = ['posix', 'win32'],
|
||||||
|
help = 'the threading type of the compiler')
|
||||||
|
parser.add_argument('--exceptions', choices = ['sjlj', 'seh', 'dwarf'],
|
||||||
|
help = 'the method to throw exceptions')
|
||||||
|
parser.add_argument('--revision', type=int,
|
||||||
|
help = 'the revision of the MinGW release')
|
||||||
|
group = parser.add_mutually_exclusive_group()
|
||||||
|
group.add_argument('-v', '--verbose', action='store_true',
|
||||||
|
help='increase the script output verbosity')
|
||||||
|
group.add_argument('-q', '--quiet', action='store_true',
|
||||||
|
help='only print errors and warning')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Create the logger
|
||||||
|
logger = logging.getLogger('mingw')
|
||||||
|
handler = logging.StreamHandler()
|
||||||
|
formatter = logging.Formatter('%(message)s')
|
||||||
|
handler.setFormatter(formatter)
|
||||||
|
logger.addHandler(handler)
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
if args.quiet:
|
||||||
|
logger.setLevel(logging.WARN)
|
||||||
|
if args.verbose:
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
# Get MinGW
|
||||||
|
root_dir = root(location = args.location, arch = args.arch,
|
||||||
|
version = args.version, threading = args.threading,
|
||||||
|
exceptions = args.exceptions, revision = args.revision,
|
||||||
|
log = logger)
|
||||||
|
|
||||||
|
sys.stdout.write('%s\n' % os.path.join(root_dir, 'bin'))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except IOError as e:
|
||||||
|
sys.stderr.write('IO error: %s\n' % e)
|
||||||
|
sys.exit(1)
|
||||||
|
except OSError as e:
|
||||||
|
sys.stderr.write('OS error: %s\n' % e)
|
||||||
|
sys.exit(1)
|
||||||
|
except KeyboardInterrupt as e:
|
||||||
|
sys.stderr.write('Killed\n')
|
||||||
|
sys.exit(1)
|
@ -32,6 +32,11 @@ set_target_properties(benchmark PROPERTIES
|
|||||||
SOVERSION ${GENERIC_LIB_SOVERSION}
|
SOVERSION ${GENERIC_LIB_SOVERSION}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# We need extra libraries on Windows
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||||
|
target_link_libraries(benchmark Shlwapi)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable)
|
# Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable)
|
||||||
install(
|
install(
|
||||||
TARGETS benchmark
|
TARGETS benchmark
|
||||||
|
@ -13,9 +13,12 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "benchmark/benchmark.h"
|
#include "benchmark/benchmark.h"
|
||||||
|
#include "internal_macros.h"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#ifndef OS_WINDOWS
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#endif
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
#include "commandlineflags.h"
|
#include "commandlineflags.h"
|
||||||
#include "internal_macros.h"
|
#include "internal_macros.h"
|
||||||
|
|
||||||
|
#ifdef OS_WINDOWS
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
DECLARE_bool(color_print);
|
DECLARE_bool(color_print);
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
|
@ -19,10 +19,14 @@
|
|||||||
|
|
||||||
#include "internal_macros.h"
|
#include "internal_macros.h"
|
||||||
|
|
||||||
|
#ifdef OS_WINDOWS
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
#ifdef OS_WINDOWS
|
#ifdef OS_WINDOWS
|
||||||
// Window's _sleep takes milliseconds argument.
|
// Window's Sleep takes milliseconds argument.
|
||||||
void SleepForMilliseconds(int milliseconds) { _sleep(milliseconds); }
|
void SleepForMilliseconds(int milliseconds) { Sleep(milliseconds); }
|
||||||
void SleepForSeconds(double seconds) {
|
void SleepForSeconds(double seconds) {
|
||||||
SleepForMilliseconds(static_cast<int>(kNumMillisPerSecond * seconds));
|
SleepForMilliseconds(static_cast<int>(kNumMillisPerSecond * seconds));
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,19 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "sysinfo.h"
|
#include "sysinfo.h"
|
||||||
|
#include "internal_macros.h"
|
||||||
|
|
||||||
|
#ifdef OS_WINDOWS
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
#include <Windows.h>
|
||||||
|
#else
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
|
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@ -227,7 +233,6 @@ void InitializeSystemInfo() {
|
|||||||
// TODO: also figure out cpuinfo_num_cpus
|
// TODO: also figure out cpuinfo_num_cpus
|
||||||
|
|
||||||
#elif defined OS_WINDOWS
|
#elif defined OS_WINDOWS
|
||||||
#pragma comment(lib, "shlwapi.lib") // for SHGetValue()
|
|
||||||
// In NT, read MHz from the registry. If we fail to do so or we're in win9x
|
// In NT, read MHz from the registry. If we fail to do so or we're in win9x
|
||||||
// then make a crude estimate.
|
// then make a crude estimate.
|
||||||
OSVERSIONINFO os;
|
OSVERSIONINFO os;
|
||||||
@ -238,7 +243,7 @@ void InitializeSystemInfo() {
|
|||||||
SHGetValueA(HKEY_LOCAL_MACHINE,
|
SHGetValueA(HKEY_LOCAL_MACHINE,
|
||||||
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
|
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
|
||||||
"~MHz", nullptr, &data, &data_size)))
|
"~MHz", nullptr, &data, &data_size)))
|
||||||
cpuinfo_cycles_per_second = (int64)data * (int64)(1000 * 1000); // was mhz
|
cpuinfo_cycles_per_second = (int64_t)data * (int64_t)(1000 * 1000); // was mhz
|
||||||
else
|
else
|
||||||
cpuinfo_cycles_per_second = EstimateCyclesPerSecond();
|
cpuinfo_cycles_per_second = EstimateCyclesPerSecond();
|
||||||
// TODO: also figure out cpuinfo_num_cpus
|
// TODO: also figure out cpuinfo_num_cpus
|
||||||
@ -274,9 +279,9 @@ void InitializeSystemInfo() {
|
|||||||
}
|
}
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
||||||
#ifndef OS_WINDOWS
|
|
||||||
// getrusage() based implementation of MyCPUUsage
|
// getrusage() based implementation of MyCPUUsage
|
||||||
static double MyCPUUsageRUsage() {
|
static double MyCPUUsageRUsage() {
|
||||||
|
#ifndef OS_WINDOWS
|
||||||
struct rusage ru;
|
struct rusage ru;
|
||||||
if (getrusage(RUSAGE_SELF, &ru) == 0) {
|
if (getrusage(RUSAGE_SELF, &ru) == 0) {
|
||||||
return (static_cast<double>(ru.ru_utime.tv_sec) +
|
return (static_cast<double>(ru.ru_utime.tv_sec) +
|
||||||
@ -286,8 +291,25 @@ static double MyCPUUsageRUsage() {
|
|||||||
} else {
|
} else {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
HANDLE proc = GetCurrentProcess();
|
||||||
|
FILETIME creation_time;
|
||||||
|
FILETIME exit_time;
|
||||||
|
FILETIME kernel_time;
|
||||||
|
FILETIME user_time;
|
||||||
|
ULARGE_INTEGER kernel;
|
||||||
|
ULARGE_INTEGER user;
|
||||||
|
GetProcessTimes(proc, &creation_time, &exit_time, &kernel_time, &user_time);
|
||||||
|
kernel.HighPart = kernel_time.dwHighDateTime;
|
||||||
|
kernel.LowPart = kernel_time.dwLowDateTime;
|
||||||
|
user.HighPart = user_time.dwHighDateTime;
|
||||||
|
user.LowPart = user_time.dwLowDateTime;
|
||||||
|
return (static_cast<double>(kernel.QuadPart) +
|
||||||
|
static_cast<double>(user.QuadPart)) / 1.0E-7;
|
||||||
|
#endif // OS_WINDOWS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OS_WINDOWS
|
||||||
static bool MyCPUUsageCPUTimeNsLocked(double* cputime) {
|
static bool MyCPUUsageCPUTimeNsLocked(double* cputime) {
|
||||||
static int cputime_fd = -1;
|
static int cputime_fd = -1;
|
||||||
if (cputime_fd == -1) {
|
if (cputime_fd == -1) {
|
||||||
@ -313,8 +335,10 @@ static bool MyCPUUsageCPUTimeNsLocked(double* cputime) {
|
|||||||
*cputime = static_cast<double>(result) / 1e9;
|
*cputime = static_cast<double>(result) / 1e9;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif // OS_WINDOWS
|
||||||
|
|
||||||
double MyCPUUsage() {
|
double MyCPUUsage() {
|
||||||
|
#ifndef OS_WINDOWS
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> l(cputimens_mutex);
|
std::lock_guard<std::mutex> l(cputimens_mutex);
|
||||||
static bool use_cputime_ns = true;
|
static bool use_cputime_ns = true;
|
||||||
@ -328,10 +352,12 @@ double MyCPUUsage() {
|
|||||||
use_cputime_ns = false;
|
use_cputime_ns = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // OS_WINDOWS
|
||||||
return MyCPUUsageRUsage();
|
return MyCPUUsageRUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
double ChildrenCPUUsage() {
|
double ChildrenCPUUsage() {
|
||||||
|
#ifndef OS_WINDOWS
|
||||||
struct rusage ru;
|
struct rusage ru;
|
||||||
if (getrusage(RUSAGE_CHILDREN, &ru) == 0) {
|
if (getrusage(RUSAGE_CHILDREN, &ru) == 0) {
|
||||||
return (static_cast<double>(ru.ru_utime.tv_sec) +
|
return (static_cast<double>(ru.ru_utime.tv_sec) +
|
||||||
@ -341,8 +367,11 @@ double ChildrenCPUUsage() {
|
|||||||
} else {
|
} else {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
}
|
#else
|
||||||
|
// TODO: Not sure what this even means on Windows
|
||||||
|
return 0.0;
|
||||||
#endif // OS_WINDOWS
|
#endif // OS_WINDOWS
|
||||||
|
}
|
||||||
|
|
||||||
double CyclesPerSecond(void) {
|
double CyclesPerSecond(void) {
|
||||||
std::call_once(cpuinfo_init, InitializeSystemInfo);
|
std::call_once(cpuinfo_init, InitializeSystemInfo);
|
||||||
|
Loading…
Reference in New Issue
Block a user