Skip to content
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Auto detect text files and perform LF normalization
* text=auto

# Custom for Visual Studio
*.sln merge=union
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be the only one we care about, I believe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 2579604.

7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,10 @@ cmake_install.cmake
lib/
tags
.ycm_extra_conf.pyc

# Visual Studio files
/msvc/[Dd]ebug*/
/msvc/[Rr]elease*/
/msvc/*.opensdf
/msvc/*.sdf
/msvc/*.suo
7 changes: 5 additions & 2 deletions include/benchmark/benchmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,19 @@ BENCHMARK(BM_MultiThreaded)->Threads(4);
#ifndef BENCHMARK_BENCHMARK_H_
#define BENCHMARK_BENCHMARK_H_

#include <stdint.h>
#include "port.h"

#include <stdint.h>
#include <functional>
#include <memory>
#include <pthread.h>
#include <string>
#include <vector>

#include "macros.h"

struct _pthread_v;
typedef struct _pthread_v* pthread_t;

namespace benchmark {
class BenchmarkReporter;

Expand Down
11 changes: 11 additions & 0 deletions include/benchmark/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];

#define arraysize(array) (sizeof(ArraySizeHelper(array)))

// If you include both this library and glog, glog must come first.
#ifndef CHECK
#define CHECK(b) \
do { \
if (!(b)) assert(false); \
Expand All @@ -45,7 +47,15 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
#define CHECK_LE(a, b) CHECK((a) <= (b))
#define CHECK_GT(a, b) CHECK((a) > (b))
#define CHECK_LT(a, b) CHECK((a) < (b))
#endif

#ifdef _MSC_VER
#define ATTRIBUTE_UNUSED
#define ATTRIBUTE_ALWAYS_INLINE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be defined to __forceinline, or is the order different between this and gcc attributes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The syntax is different: __forceinline is instead of inline while the gcc attribute is in addition to inline. This could probably be handled with more complicated macros, but it's not worth the bother, I have never seen __forceinline produce useful results.

#define HAVE_ATTRIBUTE_ALWAYS_INLINE 0
#define ATTRIBUTE_NOINLINE
#define HAVE_ATTRIBUTE_NOINLINE 0
#else
//
// Prevent the compiler from complaining about or optimizing away variables
// that appear unused.
Expand All @@ -58,5 +68,6 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
#define HAVE_ATTRIBUTE_ALWAYS_INLINE 1
#define ATTRIBUTE_NOINLINE __attribute__((noinline))
#define HAVE_ATTRIBUTE_NOINLINE 1
#endif

#endif // BENCHMARK_MACROS_H_
107 changes: 107 additions & 0 deletions include/benchmark/port.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ---
* Author: Craig Silverstein
*
* These are some portability typedefs and defines to make it a bit
* easier to compile this code under VC++.
*
* Several of these are taken from glib:
* http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
*/

#ifndef BENCHMARK_PORT_H_
#define BENCHMARK_PORT_H_

#ifdef _WIN32

#define NOMINMAX

#ifdef _MSC_VER
#define COMPILER_MSVC
#endif

#include <windows.h>
#include <winsock.h> /* for timeval */
#include <stdio.h> /* read in vsnprintf decl. before redifining it */
#include <time.h> /* for localtime_s() */
#include <Shlwapi.h>

/* 4244: otherwise we get problems when substracting two size_t's to an int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should be able to remove a bunch of these given that we don't compile nearly the same set of things that Craig Silverstein had in mind when he wrote this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have trimmed down port.{h,cc} to the bare minimum in 5454072.

* 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror()
*/
#pragma warning(disable:4244 4996)

/* We can't just use _vsnprintf and _snprintf as drop-in-replacements,
* because they don't always NUL-terminate. :-( We also can't use the
* name vsnprintf, since windows defines that (but not snprintf (!)).
*/
extern int snprintf(char *str, size_t size,
const char *format, ...);

inline struct tm* localtime_r(const time_t* timep, struct tm* result) {
localtime_s(result, timep);
return result;
}

inline struct tm* gmtime_r(const time_t *timer, struct tm *result) {
errno_t e = gmtime_s(result, timer);
return result;
}

extern int gettimeofday(struct timeval *tv, void* tz);

// The rest of this file is a poor man's config.h.

#undef HAVE_GNUREGEX_H
#undef HAVE_PTHREAD_H
#define HAVE_REGEX
#undef HAVE_REGEX_H
#undef HAVE_SEMAPHORE_H
#undef HAVE_SYS_RESOURCE_H
#undef HAVE_SYS_SYSCTL_H
#undef HAVE_SYS_TIME_H
#undef HAVE_UNISTD_H

#else /* _WIN32 */

#undef HAVE_GNUREGEX_H
#define HAVE_PTHREAD_H
#undef HAVE_REGEX
#define HAVE_REGEX_H
#define HAVE_SEMAPHORE_H
#define HAVE_SYS_RESOURCE_H
#define HAVE_SYS_SYSCTL_H
#define HAVE_SYS_TIME_H
#define HAVE_UNISTD_H

#endif /* _WIN32 */

#endif /* BENCHMARK_PORT_H_ */
17 changes: 16 additions & 1 deletion src/benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,19 @@
#include "colorprint.h"
#include "commandlineflags.h"
#include "mutex_lock.h"
#include "pthread.h"
#include "re.h"
#include "sleep.h"
#include "stat.h"
#include "sysinfo.h"
#include "walltime.h"

#if defined HAVE_SYS_TIME_H
#include <sys/time.h>
#include <pthread.h>
#endif
#if defined HAVE_SEMAPHORE_H
#include <semaphore.h>
#endif
#include <string.h>

#include <algorithm>
Expand Down Expand Up @@ -1151,7 +1155,18 @@ bool State::FinishInterval() {
const double accumulated_time = walltime::Now() - start_time_;
const double total_overhead = overhead * iterations_;
CHECK_LT(pause_real_time_, accumulated_time);
#if defined OS_WINDOWS
// The clock accuracy is poor on Windows.
if (pause_real_time_ + total_overhead >= accumulated_time) {
fprintf(stderr,
"Overhead measurement flawed: test ran faster (%f s) than expected "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there might be better advice here .. set a minimum time using --benchmark_min_time ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this doesn't help, even with a very long --benchmark_min_time. I'll need to rethink the way overhead is measured on Windows because the real-time numbers look semi-random at the moment (but the CPU times are good, which is what I am after at this point).

"overhead (%f s). Try again and be aware that elapsed times may "
"be unreliable.\n",
accumulated_time, pause_real_time_ + total_overhead);
}
#else
CHECK_LT(pause_real_time_ + total_overhead, accumulated_time);
#endif
data.real_accumulated_time =
accumulated_time - (pause_real_time_ + total_overhead);
data.cpu_accumulated_time = (MyCPUUsage() + ChildrenCPUUsage()) -
Expand Down
1 change: 1 addition & 0 deletions src/colorprint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <stdarg.h>

#include "commandlineflags.h"
#include "benchmark/port.h"

DECLARE_bool(color_print);

Expand Down
5 changes: 5 additions & 0 deletions src/cycleclock.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
#ifndef BENCHMARK_CYCLECLOCK_H_
#define BENCHMARK_CYCLECLOCK_H_

#include "benchmark/port.h"

#include <stdint.h>

#if defined(OS_MACOSX)
#include <mach/mach_time.h>
#endif

// For MSVC, we want to use '_asm rdtsc' when possible (since it works
// with even ancient MSVC compilers), and when not possible the
// __rdtsc intrinsic, declared in <intrin.h>. Unfortunately, in some
Expand All @@ -37,7 +40,9 @@
extern "C" uint64_t __rdtsc();
#pragma intrinsic(__rdtsc)
#endif
#if defined HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#include "benchmark/macros.h"

Expand Down
2 changes: 1 addition & 1 deletion src/mutex_lock.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef BENCHMARK_MUTEX_LOCK_H_
#define BENCHMARK_MUTEX_LOCK_H_

#include <pthread.h>
#include "pthread.h"

namespace benchmark {
class mutex_lock {
Expand Down
69 changes: 69 additions & 0 deletions src/port.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ---
* Author: Craig Silverstein
* Copied from google-perftools and modified by Shinichiro Hamaji
*/

#ifndef _WIN32
# error You should only be including windows/port.cc in a windows environment!
#endif

#include "benchmark/port.h"

#include <stdarg.h> // for va_list, va_start, va_end
#include <stdint.h>

// This calls the windows _vsnprintf, but always NUL-terminate.
int snprintf(char *str, size_t size, const char *format, ...) {
va_list ap;
va_start(ap, format);
const int r = vsnprintf(str, size, format, ap);
va_end(ap);
return r;
}

// Based on: https://code.google.com/p/google-glog/source/browse/trunk/src/utilities.cc
int gettimeofday(struct timeval *tv, void* tz) {
#define EPOCHFILETIME (116444736000000000ULL)
FILETIME ft;
LARGE_INTEGER li;
uint64_t tt;

// This seems to return time with a granularity of 10 ms on Windows 7. Sigh.
GetSystemTimeAsFileTime(&ft);
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
tt = (li.QuadPart - EPOCHFILETIME) / 10;
tv->tv_sec = tt / 1000000;
tv->tv_usec = tt % 1000000;

return 0;
}
14 changes: 14 additions & 0 deletions src/pthread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef BENCHMARK_PTHREAD_H_
#define BENCHMARK_PTHREAD_H_

#include "benchmark/port.h"

#if defined HAVE_PTHREAD_H
#include <pthread.h>
#endif

#if defined OS_WINDOWS
#include "windows/pthread.h"
#endif

#endif // BENCHMARK_PTHREAD_H_
10 changes: 10 additions & 0 deletions src/re.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ namespace benchmark {
Regex::Regex() : init_(false) { }

bool Regex::Init(const std::string& spec, std::string* error) {
#if defined HAVE_REGEX
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please pull this out. i actually had some issues when i tried using std::regex for this project as the matching wasn't quite the same. I don't remember the details, i'm afraid, but i'd want much more testing before making this change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nominally going to be addressed by #30, but I would want to merge that (and test it) before moving forward with the rest of this patch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dominichamon: I don't understand why you want it pulled out. There is just no alternative on Windows. We can argue whether the C++11 library is the right thing to use in general (that's the topic of #30) but there is no other way to do it on Windows. Even if the regex matching is not quite the same, it's probably no big deal, it's just for a flag anyway.
@ckennelly: Sorry, I'm not doing that. #30 can wait. Having to resolve all the conflicts that would result from doing #30 before this PR is not my idea of fun (and is a great way to introduce bugs).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the changes here are confined entirely to these two files, you would be able to revert the changes to re.cc and re.h before rebasing. There wouldn't be any merge conflicts to resolve.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the point: I don't think that the changes will be restricted to these two files. There is no reason to have re.{h,cc} anymore if we use the C++11 regex. We might as well include regex in benchmark.cc and use it directly in FindBenchmarks (after all, we don't wrap vector or map in an auxiliary class). Then regex_test.cc goes away too (we don't test standard libraries). This significantly simplifies the code, but the restructuring is sizeable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we won't just use regex directly. we need to support older compilers that don't have it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this discussion is superseded by #41 anyway.

re_ = std::regex(spec, std::regex::extended | std::regex::nosubs);
#else
int ec = regcomp(&re_, spec.c_str(), REG_EXTENDED | REG_NOSUB);
if (ec != 0) {
if (error) {
Expand All @@ -38,13 +41,16 @@ bool Regex::Init(const std::string& spec, std::string* error) {
return false;
}

#endif
init_ = true;
return true;
}

Regex::~Regex() {
if (init_) {
#if !defined HAVE_REGEX
regfree(&re_);
#endif
}
}

Expand All @@ -53,7 +59,11 @@ bool Regex::Match(const std::string& str) {
return false;
}

#if defined HAVE_REGEX
return std::regex_search(str, re_);
#else
return regexec(&re_, str.c_str(), 0, NULL, 0) == 0;
#endif
}

} // end namespace benchmark
Loading