Commit f437331f authored by Russ Cox's avatar Russ Cox

time: faster Nanoseconds call

runtime knows how to get the time of day
without allocating memory.

R=golang-dev, dsymonds, dave, hectorchu, r, cw
CC=golang-dev
https://golang.org/cl/5297078
parent 31452a36
...@@ -98,6 +98,7 @@ OFILES=\ ...@@ -98,6 +98,7 @@ OFILES=\
symtab.$O\ symtab.$O\
sys.$O\ sys.$O\
thread.$O\ thread.$O\
time.$O\
traceback.$O\ traceback.$O\
$(OFILES_$(GOARCH))\ $(OFILES_$(GOARCH))\
$(OFILES_$(GOOS))\ $(OFILES_$(GOOS))\
......
...@@ -60,20 +60,27 @@ TEXT runtime·setitimer(SB),7,$0 ...@@ -60,20 +60,27 @@ TEXT runtime·setitimer(SB),7,$0
INT $0x80 INT $0x80
RET RET
// void gettime(int64 *sec, int32 *usec) // int64 nanotime(void) so really
TEXT runtime·gettime(SB), 7, $32 // void nanotime(int64 *nsec)
TEXT runtime·nanotime(SB), 7, $32
LEAL 12(SP), AX // must be non-nil, unused LEAL 12(SP), AX // must be non-nil, unused
MOVL AX, 4(SP) MOVL AX, 4(SP)
MOVL $0, 8(SP) // time zone pointer MOVL $0, 8(SP) // time zone pointer
MOVL $116, AX MOVL $116, AX
INT $0x80 INT $0x80
MOVL DX, BX
MOVL sec+0(FP), DI
MOVL AX, (DI) // sec is in AX, usec in BX
MOVL $0, 4(DI) // zero extend 32 -> 64 // convert to DX:AX nsec
MOVL $1000000000, CX
MOVL usec+4(FP), DI MULL CX
MOVL DX, (DI) IMULL $1000, BX
ADDL BX, AX
ADCL $0, DX
MOVL ret+0(FP), DI
MOVL AX, 0(DI)
MOVL DX, 4(DI)
RET RET
TEXT runtime·sigaction(SB),7,$0 TEXT runtime·sigaction(SB),7,$0
......
...@@ -55,16 +55,18 @@ TEXT runtime·setitimer(SB), 7, $0 ...@@ -55,16 +55,18 @@ TEXT runtime·setitimer(SB), 7, $0
SYSCALL SYSCALL
RET RET
// void gettime(int64 *sec, int32 *usec) // int64 nanotime(void)
TEXT runtime·gettime(SB), 7, $32 TEXT runtime·nanotime(SB), 7, $32
MOVQ SP, DI // must be non-nil, unused MOVQ SP, DI // must be non-nil, unused
MOVQ $0, SI MOVQ $0, SI
MOVL $(0x2000000+116), AX MOVL $(0x2000000+116), AX
SYSCALL SYSCALL
MOVQ sec+0(FP), DI
MOVQ AX, (DI) // sec is in AX, usec in DX
MOVQ usec+8(FP), DI // return nsec in AX
MOVL DX, (DI) IMULQ $1000000000, AX
IMULQ $1000, DX
ADDQ DX, AX
RET RET
TEXT runtime·sigaction(SB),7,$0 TEXT runtime·sigaction(SB),7,$0
......
...@@ -106,23 +106,31 @@ TEXT runtime·setitimer(SB), 7, $-4 ...@@ -106,23 +106,31 @@ TEXT runtime·setitimer(SB), 7, $-4
INT $0x80 INT $0x80
RET RET
TEXT runtime·gettime(SB), 7, $32 // int64 nanotime(void) so really
// void nanotime(int64 *nsec)
TEXT runtime·nanotime(SB), 7, $32
MOVL $116, AX MOVL $116, AX
LEAL 12(SP), BX LEAL 12(SP), BX
MOVL BX, 4(SP) MOVL BX, 4(SP)
MOVL $0, 8(SP) MOVL $0, 8(SP)
INT $0x80 INT $0x80
MOVL 12(SP), AX // sec
MOVL 16(SP), BX // usec
MOVL 12(SP), BX // sec // sec is in AX, usec in BX
MOVL sec+0(FP), DI // convert to DX:AX nsec
MOVL BX, (DI) MOVL $1000000000, CX
MOVL $0, 4(DI) // zero extend 32 -> 64 bits MULL CX
IMULL $1000, BX
ADDL BX, AX
ADCL $0, DX
MOVL 16(SP), BX // usec MOVL ret+0(FP), DI
MOVL usec+4(FP), DI MOVL AX, 0(DI)
MOVL BX, (DI) MOVL DX, 4(DI)
RET RET
TEXT runtime·sigaction(SB),7,$-4 TEXT runtime·sigaction(SB),7,$-4
MOVL $416, AX MOVL $416, AX
INT $0x80 INT $0x80
......
...@@ -85,19 +85,19 @@ TEXT runtime·setitimer(SB), 7, $-8 ...@@ -85,19 +85,19 @@ TEXT runtime·setitimer(SB), 7, $-8
SYSCALL SYSCALL
RET RET
TEXT runtime·gettime(SB), 7, $32 TEXT runtime·nanotime(SB), 7, $32
MOVL $116, AX MOVL $116, AX
LEAQ 8(SP), DI LEAQ 8(SP), DI
MOVQ $0, SI MOVQ $0, SI
SYSCALL SYSCALL
MOVQ 8(SP), AX // sec
MOVQ 8(SP), BX // sec MOVL 16(SP), DX // usec
MOVQ sec+0(FP), DI
MOVQ BX, (DI) // sec is in AX, usec in DX
// return nsec in AX
MOVL 16(SP), BX // usec IMULQ $1000000000, AX
MOVQ usec+8(FP), DI IMULQ $1000, DX
MOVL BX, (DI) ADDQ DX, AX
RET RET
TEXT runtime·sigaction(SB),7,$-8 TEXT runtime·sigaction(SB),7,$-8
......
...@@ -95,21 +95,28 @@ TEXT runtime·mincore(SB),7,$0-24 ...@@ -95,21 +95,28 @@ TEXT runtime·mincore(SB),7,$0-24
CALL *runtime·_vdso(SB) CALL *runtime·_vdso(SB)
RET RET
TEXT runtime·gettime(SB), 7, $32 // int64 nanotime(void) so really
// void nanotime(int64 *nsec)
TEXT runtime·nanotime(SB), 7, $32
MOVL $78, AX // syscall - gettimeofday MOVL $78, AX // syscall - gettimeofday
LEAL 8(SP), BX LEAL 8(SP), BX
MOVL $0, CX MOVL $0, CX
MOVL $0, DX MOVL $0, DX
CALL *runtime·_vdso(SB) CALL *runtime·_vdso(SB)
MOVL 8(SP), AX // sec
MOVL 8(SP), BX // sec
MOVL sec+0(FP), DI
MOVL BX, (DI)
MOVL $0, 4(DI) // zero extend 32 -> 64 bits
MOVL 12(SP), BX // usec MOVL 12(SP), BX // usec
MOVL usec+4(FP), DI
MOVL BX, (DI) // sec is in AX, usec in BX
// convert to DX:AX nsec
MOVL $1000000000, CX
MULL CX
IMULL $1000, BX
ADDL BX, AX
ADCL $0, DX
MOVL ret+0(FP), DI
MOVL AX, 0(DI)
MOVL DX, 4(DI)
RET RET
TEXT runtime·rt_sigaction(SB),7,$0 TEXT runtime·rt_sigaction(SB),7,$0
......
...@@ -93,19 +93,19 @@ TEXT runtime·mincore(SB),7,$0-24 ...@@ -93,19 +93,19 @@ TEXT runtime·mincore(SB),7,$0-24
SYSCALL SYSCALL
RET RET
TEXT runtime·gettime(SB), 7, $32 TEXT runtime·nanotime(SB), 7, $32
LEAQ 8(SP), DI LEAQ 8(SP), DI
MOVQ $0, SI MOVQ $0, SI
MOVQ $0xffffffffff600000, AX MOVQ $0xffffffffff600000, AX
CALL AX CALL AX
MOVQ 8(SP), AX // sec
MOVQ 8(SP), BX // sec MOVL 16(SP), DX // usec
MOVQ sec+0(FP), DI
MOVQ BX, (DI) // sec is in AX, usec in DX
// return nsec in AX
MOVL 16(SP), BX // usec IMULQ $1000000000, AX
MOVQ usec+8(FP), DI IMULQ $1000, DX
MOVL BX, (DI) ADDQ DX, AX
RET RET
TEXT runtime·rt_sigaction(SB),7,$0-32 TEXT runtime·rt_sigaction(SB),7,$0-32
......
...@@ -127,14 +127,14 @@ TEXT runtime·mincore(SB),7,$0 ...@@ -127,14 +127,14 @@ TEXT runtime·mincore(SB),7,$0
SWI $0 SWI $0
RET RET
TEXT runtime·gettime(SB),7,$32 // int64 nanotime(void) so really
// void nanotime(int64 *nsec)
TEXT runtime·nanotime(SB),7,$32
/* dummy version - return 0,0 */ /* dummy version - return 0,0 */
MOVW $0, R1 MOVW $0, R1
MOVW 0(FP), R0 MOVW 0(FP), R0
MOVW R1, 0(R0) MOVW R1, 0(R0)
MOVW R1, 4(R0) MOVW R1, 4(R0)
MOVW 4(FP), R0
MOVW R1, 0(R0)
/* /*
attempt at real version - seg faults attempt at real version - seg faults
......
...@@ -91,21 +91,28 @@ TEXT runtime·setitimer(SB),7,$-4 ...@@ -91,21 +91,28 @@ TEXT runtime·setitimer(SB),7,$-4
INT $0x80 INT $0x80
RET RET
TEXT runtime·gettime(SB),7,$32 // int64 nanotime(void) so really
// void nanotime(int64 *nsec)
TEXT runtime·nanotime(SB),7,$32
MOVL $116, AX MOVL $116, AX
LEAL 12(SP), BX LEAL 12(SP), BX
MOVL BX, 4(SP) MOVL BX, 4(SP)
MOVL $0, 8(SP) MOVL $0, 8(SP)
INT $0x80 INT $0x80
MOVL 12(SP), AX // sec
MOVL 12(SP), BX // sec
MOVL sec+0(FP), DI
MOVL BX, (DI)
MOVL $0, 4(DI) // zero extend 32 -> 64 bits
MOVL 16(SP), BX // usec MOVL 16(SP), BX // usec
MOVL usec+4(FP), DI
MOVL BX, (DI) // sec is in AX, usec in BX
// convert to DX:AX nsec
MOVL $1000000000, CX
MULL CX
IMULL $1000, BX
ADDL BX, AX
ADCL $0, DX
MOVL ret+0(FP), DI
MOVL AX, 0(DI)
MOVL DX, 4(DI)
RET RET
TEXT runtime·sigaction(SB),7,$-4 TEXT runtime·sigaction(SB),7,$-4
......
...@@ -133,19 +133,19 @@ TEXT runtime·setitimer(SB),7,$-8 ...@@ -133,19 +133,19 @@ TEXT runtime·setitimer(SB),7,$-8
SYSCALL SYSCALL
RET RET
TEXT runtime·gettime(SB),7,$32 TEXT runtime·nanotime(SB),7,$32
LEAQ 8(SP), DI // arg 1 - tp LEAQ 8(SP), DI // arg 1 - tp
MOVQ $0, SI // arg 2 - tzp MOVQ $0, SI // arg 2 - tzp
MOVL $116, AX // sys_gettimeofday MOVL $116, AX // sys_gettimeofday
SYSCALL SYSCALL
MOVQ 8(SP), AX // sec
MOVQ 8(SP), BX // sec
MOVQ sec+0(FP), DI
MOVQ BX, (DI)
MOVL 16(SP), BX // usec MOVL 16(SP), BX // usec
MOVQ usec+8(FP), DI
MOVL BX, (DI) // sec is in AX, usec in DX
// return nsec in AX
IMULQ $1000000000, AX
IMULQ $1000, DX
ADDQ DX, AX
RET RET
TEXT runtime·sigaction(SB),7,$-8 TEXT runtime·sigaction(SB),7,$-8
......
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
#include "runtime.h" #include "runtime.h"
void int64
runtime·gettime(int64*, int32*) runtime·nanotime(void)
{ {
// Won't compile.
} }
String String
......
...@@ -654,18 +654,6 @@ runtime·algarray[] = ...@@ -654,18 +654,6 @@ runtime·algarray[] =
[ANOEQ128] { runtime·nohash, runtime·noequal, memprint, (void*)memcopy128 }, [ANOEQ128] { runtime·nohash, runtime·noequal, memprint, (void*)memcopy128 },
}; };
int64
runtime·nanotime(void)
{
int64 sec;
int32 usec;
sec = 0;
usec = 0;
runtime·gettime(&sec, &usec);
return sec*1000000000 + (int64)usec*1000;
}
void void
runtime·Caller(int32 skip, uintptr retpc, String retfile, int32 retline, bool retbool) runtime·Caller(int32 skip, uintptr retpc, String retfile, int32 retline, bool retbool)
{ {
......
...@@ -490,7 +490,6 @@ void runtime·exitsyscall(void); ...@@ -490,7 +490,6 @@ void runtime·exitsyscall(void);
G* runtime·newproc1(byte*, byte*, int32, int32, void*); G* runtime·newproc1(byte*, byte*, int32, int32, void*);
void runtime·siginit(void); void runtime·siginit(void);
bool runtime·sigsend(int32 sig); bool runtime·sigsend(int32 sig);
void runtime·gettime(int64*, int32*);
int32 runtime·callers(int32, uintptr*, int32); int32 runtime·callers(int32, uintptr*, int32);
int32 runtime·gentraceback(byte*, byte*, byte*, G*, int32, uintptr*, int32); int32 runtime·gentraceback(byte*, byte*, byte*, G*, int32, uintptr*, int32);
int64 runtime·nanotime(void); int64 runtime·nanotime(void);
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Runtime implementations to help package time.
package time
#include "runtime.h"
func Nanoseconds() (ret int64) {
ret = runtime·nanotime();
}
...@@ -18,10 +18,9 @@ ...@@ -18,10 +18,9 @@
#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll" #pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll" #pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
#pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll" #pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
#pragma dynimport runtime·GetSystemTimeAsFileTime GetSystemTimeAsFileTime "kernel32.dll"
#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll" #pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll" #pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
#pragma dynimport runtime·QueryPerformanceCounter QueryPerformanceCounter "kernel32.dll"
#pragma dynimport runtime·QueryPerformanceFrequency QueryPerformanceFrequency "kernel32.dll"
#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll" #pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll" #pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll" #pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
...@@ -44,10 +43,9 @@ extern void *runtime·GetEnvironmentStringsW; ...@@ -44,10 +43,9 @@ extern void *runtime·GetEnvironmentStringsW;
extern void *runtime·GetProcAddress; extern void *runtime·GetProcAddress;
extern void *runtime·GetStdHandle; extern void *runtime·GetStdHandle;
extern void *runtime·GetSystemInfo; extern void *runtime·GetSystemInfo;
extern void *runtime·GetSystemTimeAsFileTime;
extern void *runtime·GetThreadContext; extern void *runtime·GetThreadContext;
extern void *runtime·LoadLibrary; extern void *runtime·LoadLibrary;
extern void *runtime·QueryPerformanceCounter;
extern void *runtime·QueryPerformanceFrequency;
extern void *runtime·ResumeThread; extern void *runtime·ResumeThread;
extern void *runtime·SetConsoleCtrlHandler; extern void *runtime·SetConsoleCtrlHandler;
extern void *runtime·SetEvent; extern void *runtime·SetEvent;
...@@ -59,8 +57,6 @@ extern void *runtime·timeBeginPeriod; ...@@ -59,8 +57,6 @@ extern void *runtime·timeBeginPeriod;
extern void *runtime·WaitForSingleObject; extern void *runtime·WaitForSingleObject;
extern void *runtime·WriteFile; extern void *runtime·WriteFile;
static int64 timerfreq;
static int32 static int32
getproccount(void) getproccount(void)
{ {
...@@ -77,7 +73,6 @@ runtime·osinit(void) ...@@ -77,7 +73,6 @@ runtime·osinit(void)
runtime·stdcall(runtime·DuplicateHandle, 7, runtime·stdcall(runtime·DuplicateHandle, 7,
(uintptr)-1, (uintptr)-2, (uintptr)-1, &m->thread, (uintptr)-1, (uintptr)-2, (uintptr)-1, &m->thread,
(uintptr)0, (uintptr)0, (uintptr)DUPLICATE_SAME_ACCESS); (uintptr)0, (uintptr)0, (uintptr)DUPLICATE_SAME_ACCESS);
runtime·stdcall(runtime·QueryPerformanceFrequency, 1, &timerfreq);
runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1); runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1); runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1);
runtime·ncpu = getproccount(); runtime·ncpu = getproccount();
...@@ -197,15 +192,16 @@ runtime·minit(void) ...@@ -197,15 +192,16 @@ runtime·minit(void)
{ {
} }
void int64
runtime·gettime(int64 *sec, int32 *usec) runtime·nanotime(void)
{ {
int64 count; int64 filetime;
runtime·stdcall(runtime·GetSystemTimeAsFileTime, 1, &filetime);
runtime·stdcall(runtime·QueryPerformanceCounter, 1, &count); // Filetime is 100s of nanoseconds since January 1, 1601.
*sec = count / timerfreq; // Convert to nanoseconds since January 1, 1970.
count %= timerfreq; return (filetime - 116444736000000000LL) * 100LL;
*usec = count*1000000 / timerfreq;
} }
// Calling stdcall on os stack. // Calling stdcall on os stack.
......
...@@ -4,27 +4,17 @@ ...@@ -4,27 +4,17 @@
package time package time
import "os"
// Seconds reports the number of seconds since the Unix epoch, // Seconds reports the number of seconds since the Unix epoch,
// January 1, 1970 00:00:00 UTC. // January 1, 1970 00:00:00 UTC.
func Seconds() int64 { func Seconds() int64 {
sec, _, err := os.Time() return Nanoseconds() / 1e9
if err != nil {
panic(err)
}
return sec
} }
// Nanoseconds is implemented by package runtime.
// Nanoseconds reports the number of nanoseconds since the Unix epoch, // Nanoseconds reports the number of nanoseconds since the Unix epoch,
// January 1, 1970 00:00:00 UTC. // January 1, 1970 00:00:00 UTC.
func Nanoseconds() int64 { func Nanoseconds() int64
sec, nsec, err := os.Time()
if err != nil {
panic(err)
}
return sec*1e9 + nsec
}
// Sleep pauses the current goroutine for at least ns nanoseconds. // Sleep pauses the current goroutine for at least ns nanoseconds.
// Higher resolution sleeping may be provided by syscall.Nanosleep // Higher resolution sleeping may be provided by syscall.Nanosleep
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment