1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
https://github.com/google/benchmark/commit/f65741b2bd92461dc2c816056eb9c996ae48ad62
https://github.com/google/benchmark/commit/077db43001b42af3ad23e993b2bdcb4fadb7bcf8
https://github.com/google/benchmark/commit/39be87d3004ff9ff4cdf736651af80c3d15e2497
https://github.com/google/benchmark/commit/c24774dc4f4402c3ad150363321cc972ed2669e7
From f65741b2bd92461dc2c816056eb9c996ae48ad62 Mon Sep 17 00:00:00 2001
From: Helge Deller <deller@gmx.de>
Date: Wed, 8 Jan 2025 13:03:53 +0100
Subject: [PATCH] cycleclock: Support for PA-RISC (hppa) architecture (#1894)
Co-authored-by: dominic <510002+dmah42@users.noreply.github.com>
---
src/cycleclock.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/cycleclock.h b/src/cycleclock.h
index bd62f5d7e7..7852f3df52 100644
--- a/src/cycleclock.h
+++ b/src/cycleclock.h
@@ -229,6 +229,16 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
struct timeval tv;
gettimeofday(&tv, nullptr);
return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
+#elif defined(__hppa__)
+ // HP PA-RISC provides a user-readable clock counter (cr16), but
+ // it's not syncronized across CPUs and only 32-bit wide when programs
+ // are built as 32-bit binaries.
+ // Use clock_gettime(CLOCK_MONOTONIC, ...) instead of gettimeofday
+ // because is provides nanosecond resolution.
+ // Initialize to always return 0 if clock_gettime fails.
+ struct timespec ts = {0, 0};
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return static_cast<int64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec;
#else
// The soft failover to a generic implementation is automatic only for ARM.
// For other platforms the developer is expected to make an attempt to create
From 077db43001b42af3ad23e993b2bdcb4fadb7bcf8 Mon Sep 17 00:00:00 2001
From: Helge Deller <deller@gmx.de>
Date: Wed, 8 Jan 2025 17:54:08 +0100
Subject: [PATCH] cycleclock: Use cock_gettime() as fallback for any Linux
architecture (#1899)
The Linux kernel provides the clock_gettime() functions since a long
time already, so it's possible to use it as a generic fallback option
for any architecture if no other (better) possibility has been provided
instead.
I noticed the benchmark package failed to build on debian on the SH-4
architecture, so with this change SH-4 is now the first user of this
fallback option.
---
src/cycleclock.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/cycleclock.h b/src/cycleclock.h
index 7852f3df5..03e02f805 100644
--- a/src/cycleclock.h
+++ b/src/cycleclock.h
@@ -229,10 +229,12 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
struct timeval tv;
gettimeofday(&tv, nullptr);
return static_cast<int64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
-#elif defined(__hppa__)
+#elif defined(__hppa__) || defined(__linux__)
+ // Fallback for all other architectures with a recent Linux kernel, e.g.:
// HP PA-RISC provides a user-readable clock counter (cr16), but
// it's not syncronized across CPUs and only 32-bit wide when programs
// are built as 32-bit binaries.
+ // Same for SH-4 and possibly others.
// Use clock_gettime(CLOCK_MONOTONIC, ...) instead of gettimeofday
// because is provides nanosecond resolution.
// Initialize to always return 0 if clock_gettime fails.
From 39be87d3004ff9ff4cdf736651af80c3d15e2497 Mon Sep 17 00:00:00 2001
From: Helge Deller <deller@gmx.de>
Date: Thu, 9 Jan 2025 11:47:29 +0100
Subject: [PATCH] Fix runtime crash when parsing /proc/cpuinfo fails (#1900)
The testcase fails on sparc64, because the parsing of /proc/cpuinfo
fails and thus currently returns "0" CPUs which finally leads
to division-by-zero faults in the tests.
Fix the issue by returning at least "1" CPU which allows the
tests to run. A error message will be printed in any case.
Long-term the code should be fixed to parse the cpuinfo output
on sparch which looks like this:
...
type : sun4v
ncpus probed : 48
ncpus active : 48
---
src/sysinfo.cc | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/sysinfo.cc b/src/sysinfo.cc
index 49bff75e5..ce14b8d8e 100644
--- a/src/sysinfo.cc
+++ b/src/sysinfo.cc
@@ -561,10 +561,12 @@ int GetNumCPUsImpl() {
}
int GetNumCPUs() {
- const int num_cpus = GetNumCPUsImpl();
+ int num_cpus = GetNumCPUsImpl();
if (num_cpus < 1) {
std::cerr << "Unable to extract number of CPUs. If your platform uses "
"/proc/cpuinfo, custom support may need to be added.\n";
+ /* There is at least one CPU which we run on. */
+ num_cpus = 1;
}
return num_cpus;
}
From c24774dc4f4402c3ad150363321cc972ed2669e7 Mon Sep 17 00:00:00 2001
From: Helge Deller <deller@gmx.de>
Date: Thu, 9 Jan 2025 17:07:43 +0100
Subject: [PATCH] Get number of CPUs with sysconf() on Linux (#1901)
* Get number of CPUs with sysconf() on Linux
Avoid parsing the /proc/cpuinfo just to get number of CPUs.
Instead use the portable function provided by glibc.
* Update sysinfo.cc
---
src/sysinfo.cc | 54 +++-----------------------------------------------
1 file changed, 3 insertions(+), 51 deletions(-)
diff --git a/src/sysinfo.cc b/src/sysinfo.cc
index ce14b8d8e..eddd430e6 100644
--- a/src/sysinfo.cc
+++ b/src/sysinfo.cc
@@ -492,14 +492,14 @@ int GetNumCPUsImpl() {
GetSystemInfo(&sysinfo);
// number of logical processors in the current group
return static_cast<int>(sysinfo.dwNumberOfProcessors);
-#elif defined(BENCHMARK_OS_SOLARIS)
+#elif defined(__linux__) || defined(BENCHMARK_OS_SOLARIS)
// Returns -1 in case of a failure.
- long num_cpu = sysconf(_SC_NPROCESSORS_ONLN);
+ int num_cpu = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
if (num_cpu < 0) {
PrintErrorAndDie("sysconf(_SC_NPROCESSORS_ONLN) failed with error: ",
strerror(errno));
}
- return (int)num_cpu;
+ return num_cpu;
#elif defined(BENCHMARK_OS_QNX)
return static_cast<int>(_syspage_ptr->num_cpu);
#elif defined(BENCHMARK_OS_QURT)
@@ -508,54 +508,6 @@ int GetNumCPUsImpl() {
hardware_threads.max_hthreads = 1;
}
return hardware_threads.max_hthreads;
-#else
- int num_cpus = 0;
- int max_id = -1;
- std::ifstream f("/proc/cpuinfo");
- if (!f.is_open()) {
- std::cerr << "Failed to open /proc/cpuinfo\n";
- return -1;
- }
-#if defined(__alpha__)
- const std::string Key = "cpus detected";
-#else
- const std::string Key = "processor";
-#endif
- std::string ln;
- while (std::getline(f, ln)) {
- if (ln.empty()) continue;
- std::size_t split_idx = ln.find(':');
- std::string value;
-#if defined(__s390__)
- // s390 has another format in /proc/cpuinfo
- // it needs to be parsed differently
- if (split_idx != std::string::npos)
- value = ln.substr(Key.size() + 1, split_idx - Key.size() - 1);
-#else
- if (split_idx != std::string::npos) value = ln.substr(split_idx + 1);
-#endif
- if (ln.size() >= Key.size() && ln.compare(0, Key.size(), Key) == 0) {
- num_cpus++;
- if (!value.empty()) {
- const int cur_id = benchmark::stoi(value);
- max_id = std::max(cur_id, max_id);
- }
- }
- }
- if (f.bad()) {
- PrintErrorAndDie("Failure reading /proc/cpuinfo");
- }
- if (!f.eof()) {
- PrintErrorAndDie("Failed to read to end of /proc/cpuinfo");
- }
- f.close();
-
- if ((max_id + 1) != num_cpus) {
- fprintf(stderr,
- "CPU ID assignments in /proc/cpuinfo seem messed up."
- " This is usually caused by a bad BIOS.\n");
- }
- return num_cpus;
#endif
BENCHMARK_UNREACHABLE();
}
|