Skip to content

Commit e94cf15

Browse files
committed
bench: Fix initialization order in registration
- backports bitcoin/bitcoin@29c5328 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 bitcoin#8910.
1 parent 151c25f commit e94cf15

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
@@ -10,7 +10,10 @@
1010
#include <iostream>
1111
#include <sys/time.h>
1212

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

1518
static double gettimedouble(void) {
1619
struct timeval tv;
@@ -20,7 +23,7 @@ static double gettimedouble(void) {
2023

2124
benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func)
2225
{
23-
benchmarks.insert(std::make_pair(name, func));
26+
benchmarks().insert(std::make_pair(name, func));
2427
}
2528

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

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

src/bench/bench.h

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

6262
class BenchRunner
6363
{
64-
static std::map<std::string, BenchFunction> benchmarks;
64+
typedef std::map<std::string, BenchFunction> BenchmarkMap;
65+
static BenchmarkMap &benchmarks();
6566

6667
public:
6768
BenchRunner(std::string name, BenchFunction func);

0 commit comments

Comments
 (0)