Further cleanup/optimization of system_time

On gcc4, we can use the __rdtsc builtin. On gcc2, provide a similar
inline-able version of rdtsc, and remove the rdtsc function written in
assembly, saving a call/ret on every call.

There has been some discussion about performance, but note that this is
only bootloader code, it is not used when the system is up and running,
therefore performance is not that critical.
This commit is contained in:
Adrien Destugues
2020-01-27 21:46:43 +01:00
parent 97e67e3f63
commit 2d697067b2
4 changed files with 15 additions and 24 deletions
+14 -5
View File
@@ -23,8 +23,6 @@
#include <string.h>
extern "C" uint64 rdtsc();
uint32 gTimeConversionFactor;
// PIT definitions
@@ -66,6 +64,17 @@ uint32 gTimeConversionFactor;
// TODO: These are arbitrary. They are here to avoid spinning indefinitely
// if the TSC just isn't stable and we can't get our desired error range.
#if __GNUC__ <= 2
// It's a builtin on later compiler versions, but not in gcc2...
static inline uint64_t __rdtsc()
{
uint64 tsc;
asm volatile ("rdtsc\n" : "=A"(tsc));
return tsc;
}
#endif
struct uint128 {
uint128(uint64 low, uint64 high = 0)
@@ -198,7 +207,7 @@ calibration_loop(uint8 desiredHighByte, uint8 channel, uint64& tscDelta,
} while (startHigh != 255);
// Read in the first TSC value
uint64 startTSC = rdtsc();
uint64 startTSC = __rdtsc();
// Wait for the PIT to count down to our desired value
uint8 endLow;
@@ -210,7 +219,7 @@ calibration_loop(uint8 desiredHighByte, uint8 channel, uint64& tscDelta,
} while (endHigh > desiredHighByte);
// And read the second TSC value
uint64 endTSC = rdtsc();
uint64 endTSC = __rdtsc();
tscDelta = endTSC - startTSC;
expired = ((startHigh << 8) | startLow) - ((endHigh << 8) | endLow);
@@ -304,7 +313,7 @@ slower_sample:
extern "C" bigtime_t
system_time()
{
uint64 tsc = rdtsc();
uint64 tsc = __rdtsc();
uint64 lo = (uint32)tsc;
uint64 hi = tsc >> 32;
return ((lo * gTimeConversionFactor) >> 32) + hi * gTimeConversionFactor;
+1 -6
View File
@@ -32,11 +32,6 @@ static ring_buffer* sDebugSyslogBuffer = NULL;
static bool sPostCleanup = false;
#ifdef PRINT_TIME_STAMPS
extern "C" uint64 rdtsc();
#endif
static void
syslog_write(const char* buffer, size_t length)
{
@@ -65,7 +60,7 @@ dprintf_args(const char *format, va_list args)
if (sNewLine) {
char timeBuffer[32];
snprintf(timeBuffer, sizeof(timeBuffer), "[%" B_PRIu64 "] ", rdtsc());
snprintf(timeBuffer, sizeof(timeBuffer), "[%" B_PRIu64 "] ", __rdtsc());
syslog_write(timeBuffer, strlen(timeBuffer));
serial_puts(timeBuffer, strlen(timeBuffer));
}
@@ -7,11 +7,6 @@
#define FUNCTION(x) .global x; .type x,@function; x
/* uint64 rdtsc() */
FUNCTION(rdtsc):
rdtsc
ret
FUNCTION(execute_n_instructions):
movl 4(%esp), %ecx
shrl $4, %ecx
-8
View File
@@ -7,14 +7,6 @@
#define FUNCTION(x) .global x; .type x,@function; x
/* uint64 rdtsc() */
FUNCTION(rdtsc):
rdtsc
/* Convert to 64-bit result in rax. */
shlq $32, %rdx
orq %rdx, %rax
ret
FUNCTION(execute_n_instructions):
movl %edi, %ecx
shrl $4, %ecx