Skip to content

Commit 582ceb1

Browse files
committed
Delete deriving mono_ticksPerMicrosecond from cpuinfo
Signed-off-by: Daniil Kashapov <daniil.kashapov.ykt@gmail.com>
1 parent a5f86e2 commit 582ceb1

File tree

1 file changed

+26
-44
lines changed

1 file changed

+26
-44
lines changed

src/monotonic.c

Lines changed: 26 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -40,69 +40,51 @@ static monotime getMonotonicUs_x86(void) {
4040
static void monotonicInit_x86linux(void) {
4141
const int bufflen = 256;
4242
char buf[bufflen];
43-
regex_t cpuGhzRegex, constTscRegex;
43+
regex_t constTscRegex;
4444
const size_t nmatch = 2;
4545
regmatch_t pmatch[nmatch];
4646
int constantTsc = 0;
4747
int rc;
4848

49-
/* Determine the number of TSC ticks in a micro-second. This is
50-
* a constant value matching the standard speed of the processor.
51-
* On modern processors, this speed remains constant even though
52-
* the actual clock speed varies dynamically for each core. */
53-
rc = regcomp(&cpuGhzRegex, "^model name\\s+:.*@ ([0-9.]+)GHz", REG_EXTENDED);
54-
assert(rc == 0);
49+
/* Calibrate TSC ticks per microsecond against CLOCK_MONOTONIC.
50+
* This determines the actual TSC frequency regardless of what
51+
* the processor model name reports. */
52+
for (int i = 0; i < TSC_CALIBRATION_ITERATIONS; ++i) {
53+
/* Calibrate TSC against CLOCK_MONOTONIC */
54+
struct timespec start, end;
55+
uint64_t tsc_start, tsc_end;
56+
57+
clock_gettime(CLOCK_MONOTONIC, &start);
58+
tsc_start = __rdtsc();
59+
usleep(10000); /* Sleep for 10ms */
60+
tsc_end = __rdtsc();
61+
clock_gettime(CLOCK_MONOTONIC, &end);
62+
63+
uint64_t elapsed_us = (end.tv_sec - start.tv_sec) * 1000000ULL + (end.tv_nsec - start.tv_nsec) / 1000;
64+
uint64_t tsc_elapsed = tsc_end - tsc_start;
65+
long sample_ticksPerMicrosecond = tsc_elapsed / elapsed_us;
66+
67+
/* Use the maximum out of TSC_CALIBRATION_ITERATIONS iterations for accuracy */
68+
if (sample_ticksPerMicrosecond > mono_ticksPerMicrosecond) {
69+
mono_ticksPerMicrosecond = sample_ticksPerMicrosecond;
70+
}
71+
}
5572

56-
/* Also check that the constant_tsc flag is present. (It should be
57-
* unless this is a really old CPU. */
73+
/* Check that the constant_tsc flag is present. (It should be
74+
* unless this is a really old CPU.) */
5875
rc = regcomp(&constTscRegex, "^flags\\s+:.* constant_tsc", REG_EXTENDED);
5976
assert(rc == 0);
6077

6178
FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
6279
if (cpuinfo != NULL) {
63-
while (fgets(buf, bufflen, cpuinfo) != NULL) {
64-
if (regexec(&cpuGhzRegex, buf, nmatch, pmatch, 0) == 0) {
65-
buf[pmatch[1].rm_eo] = '\0';
66-
double ghz = atof(&buf[pmatch[1].rm_so]);
67-
mono_ticksPerMicrosecond = (long)(ghz * 1000);
68-
break;
69-
}
70-
}
71-
/* Some CPUs may not contain clock speed in the model name */
72-
if (mono_ticksPerMicrosecond == 0) {
73-
for (int i = 0; i < TSC_CALIBRATION_ITERATIONS; ++i) {
74-
/* Calibrate TSC against CLOCK_MONOTONIC */
75-
struct timespec start, end;
76-
uint64_t tsc_start, tsc_end;
77-
78-
clock_gettime(CLOCK_MONOTONIC, &start);
79-
tsc_start = __rdtsc();
80-
usleep(10000); /* Sleep for 10ms */
81-
tsc_end = __rdtsc();
82-
clock_gettime(CLOCK_MONOTONIC, &end);
83-
84-
uint64_t elapsed_us = (end.tv_sec - start.tv_sec) * 1000000ULL + (end.tv_nsec - start.tv_nsec) / 1000;
85-
uint64_t tsc_elapsed = tsc_end - tsc_start;
86-
long sample_ticksPerMicrosecond = tsc_elapsed / elapsed_us;
87-
88-
/* Use the maximum out of TSC_CALIBRATION_ITERATIONS iterations for accuracy */
89-
if (sample_ticksPerMicrosecond > mono_ticksPerMicrosecond) {
90-
mono_ticksPerMicrosecond = sample_ticksPerMicrosecond;
91-
}
92-
}
93-
}
94-
/* Rewind file to search for constant_tsc flag */
95-
rewind(cpuinfo);
9680
while (fgets(buf, bufflen, cpuinfo) != NULL) {
9781
if (regexec(&constTscRegex, buf, nmatch, pmatch, 0) == 0) {
9882
constantTsc = 1;
9983
break;
10084
}
10185
}
102-
10386
fclose(cpuinfo);
10487
}
105-
regfree(&cpuGhzRegex);
10688
regfree(&constTscRegex);
10789

10890
if (mono_ticksPerMicrosecond == 0) {

0 commit comments

Comments
 (0)