Skip to content

Commit 29c5328

Browse files
committed
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.
1 parent b709fe7 commit 29c5328

File tree

2 files changed

+10
-9
lines changed

2 files changed

+10
-9
lines changed

src/bench/bench.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
#include <iomanip>
1010
#include <sys/time.h>
1111

12-
std::map<std::string, benchmark::BenchFunction> benchmark::BenchRunner::benchmarks;
12+
benchmark::BenchRunner::BenchmarkMap &benchmark::BenchRunner::benchmarks() {
13+
static std::map<std::string, benchmark::BenchFunction> benchmarks_map;
14+
return benchmarks_map;
15+
}
1316

1417
static double gettimedouble(void) {
1518
struct timeval tv;
@@ -19,7 +22,7 @@ static double gettimedouble(void) {
1922

2023
benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func)
2124
{
22-
benchmarks.insert(std::make_pair(name, func));
25+
benchmarks().insert(std::make_pair(name, func));
2326
}
2427

2528
void
@@ -29,12 +32,9 @@ benchmark::BenchRunner::RunAll(double elapsedTimeForOne)
2932
std::cout << "#Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << ","
3033
<< "min_cycles" << "," << "max_cycles" << "," << "average_cycles" << "\n";
3134

32-
for (std::map<std::string,benchmark::BenchFunction>::iterator it = benchmarks.begin();
33-
it != benchmarks.end(); ++it) {
34-
35-
State state(it->first, elapsedTimeForOne);
36-
benchmark::BenchFunction& func = it->second;
37-
func(state);
35+
for (const auto &p: benchmarks()) {
36+
State state(p.first, elapsedTimeForOne);
37+
p.second(state);
3838
}
3939
perf_fini();
4040
}

src/bench/bench.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ namespace benchmark {
6363

6464
class BenchRunner
6565
{
66-
static std::map<std::string, BenchFunction> benchmarks;
66+
typedef std::map<std::string, BenchFunction> BenchmarkMap;
67+
static BenchmarkMap &benchmarks();
6768

6869
public:
6970
BenchRunner(std::string name, BenchFunction func);

0 commit comments

Comments
 (0)