ref: df26766fcc3c3c3cab64756b6b77dd995cb98c63
parent: 6e061c69ca42f52638db4744136ab4856aa2909a
author: rodri <rgl@antares-labs.eu>
date: Tue Feb 25 11:46:35 EST 2025
nanosec: updated.
--- a/nanosec.c
+++ b/nanosec.c
@@ -2,41 +2,8 @@
#include <libc.h>
#include <tos.h>
-/*
- * This code is a mixture of cpuid(1) and the nanosec() found in vmx,
- * in order to force the use of nsec(2) in case we are running in a
- * virtualized environment where the clock is mis-bhyve-ing.
- */
+#define Nsec 1000000000ULL
-typedef struct Res {
- ulong ax, bx, cx, dx;
-} Res;
-
-static uchar _cpuid[] = {
- 0x5E, /* POP SI (PC) */
- 0x5D, /* POP BP (Res&) */
- 0x58, /* POP AX */
- 0x59, /* POP CX */
-
- 0x51, /* PUSH CX */
- 0x50, /* PUSH AX */
- 0x55, /* PUSH BP */
- 0x56, /* PUSH SI */
-
- 0x31, 0xDB, /* XOR BX, BX */
- 0x31, 0xD2, /* XOR DX, DX */
-
- 0x0F, 0xA2, /* CPUID */
-
- 0x89, 0x45, 0x00, /* MOV AX, 0(BP) */
- 0x89, 0x5d, 0x04, /* MOV BX, 4(BP) */
- 0x89, 0x4d, 0x08, /* MOV CX, 8(BP) */
- 0x89, 0x55, 0x0C, /* MOV DX, 12(BP) */
- 0xC3, /* RET */
-};
-
-static Res (*cpuid)(ulong ax, ulong cx) = (Res(*)(ulong, ulong)) _cpuid;
-
/*
* nsec() is wallclock and can be adjusted by timesync
* so need to use cycles() instead, but fall back to
@@ -46,54 +13,16 @@
nanosec(void)
{
static uvlong fasthz, xstart;
- char buf[13], path[128];
- ulong w;
- uvlong x, div;
- int fd;
- Res r;
+ uvlong x;
if(fasthz == ~0ULL)
return nsec() - xstart;
if(fasthz == 0){
- /* first long in a.out header */
- snprint(path, sizeof path, "/proc/%d/text", getpid());
- fd = open(path, OREAD);
- if(fd < 0)
- goto Wallclock;
- if(read(fd, buf, 4) != 4){
- close(fd);
- goto Wallclock;
- }
- close(fd);
-
- w = ((ulong *) buf)[0];
-
- switch(w){
- default:
- goto Wallclock;
- case 0x978a0000: /* amd64 */
- /* patch out POP BP -> POP AX */
- _cpuid[1] = 0x58;
- case 0xeb010000: /* 386 */
- break;
- }
- segflush(_cpuid, sizeof(_cpuid));
-
- r = cpuid(0x40000000, 0);
- ((ulong *) buf)[0] = r.bx;
- ((ulong *) buf)[1] = r.cx;
- ((ulong *) buf)[2] = r.dx;
- buf[12] = 0;
-
- if(strstr(buf, "bhyve") != nil)
- goto Wallclock;
-
if(_tos->cyclefreq){
fasthz = _tos->cyclefreq;
cycles(&xstart);
} else {
-Wallclock:
fasthz = ~0ULL;
xstart = nsec();
}
@@ -102,8 +31,8 @@
cycles(&x);
x -= xstart;
- /* this is ugly */
- for(div = 1000000000ULL; x < 0x1999999999999999ULL && div > 1 ; div /= 10ULL, x *= 10ULL);
+ uvlong q = x / fasthz;
+ uvlong r = x % fasthz;
- return x / (fasthz / div);
+ return q*Nsec + r*Nsec/fasthz;
}