bench: Fix initialization order in registration
The initialization order of global data structures in different implementation units is undefined. Making use of this is essentially gambling on what the linker does, the so-called [Static initialization order fiasco](https://isocpp.org/wiki/faq/ctors#static-init-order). In this case it apparently worked on Linux but failed on OpenBSD and FreeBSD. To create it on first use, make the registration structure local to a function. Fixes #8910.
This commit is contained in:
parent
b709fe7ffc
commit
29c53289a9
2 changed files with 10 additions and 9 deletions
|
@ -9,7 +9,10 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
std::map<std::string, benchmark::BenchFunction> benchmark::BenchRunner::benchmarks;
|
benchmark::BenchRunner::BenchmarkMap &benchmark::BenchRunner::benchmarks() {
|
||||||
|
static std::map<std::string, benchmark::BenchFunction> benchmarks_map;
|
||||||
|
return benchmarks_map;
|
||||||
|
}
|
||||||
|
|
||||||
static double gettimedouble(void) {
|
static double gettimedouble(void) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -19,7 +22,7 @@ static double gettimedouble(void) {
|
||||||
|
|
||||||
benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func)
|
benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func)
|
||||||
{
|
{
|
||||||
benchmarks.insert(std::make_pair(name, func));
|
benchmarks().insert(std::make_pair(name, func));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -29,12 +32,9 @@ benchmark::BenchRunner::RunAll(double elapsedTimeForOne)
|
||||||
std::cout << "#Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << ","
|
std::cout << "#Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << ","
|
||||||
<< "min_cycles" << "," << "max_cycles" << "," << "average_cycles" << "\n";
|
<< "min_cycles" << "," << "max_cycles" << "," << "average_cycles" << "\n";
|
||||||
|
|
||||||
for (std::map<std::string,benchmark::BenchFunction>::iterator it = benchmarks.begin();
|
for (const auto &p: benchmarks()) {
|
||||||
it != benchmarks.end(); ++it) {
|
State state(p.first, elapsedTimeForOne);
|
||||||
|
p.second(state);
|
||||||
State state(it->first, elapsedTimeForOne);
|
|
||||||
benchmark::BenchFunction& func = it->second;
|
|
||||||
func(state);
|
|
||||||
}
|
}
|
||||||
perf_fini();
|
perf_fini();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,8 @@ namespace benchmark {
|
||||||
|
|
||||||
class BenchRunner
|
class BenchRunner
|
||||||
{
|
{
|
||||||
static std::map<std::string, BenchFunction> benchmarks;
|
typedef std::map<std::string, BenchFunction> BenchmarkMap;
|
||||||
|
static BenchmarkMap &benchmarks();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BenchRunner(std::string name, BenchFunction func);
|
BenchRunner(std::string name, BenchFunction func);
|
||||||
|
|
Loading…
Reference in a new issue