1
0
mirror of https://github.com/golang/go synced 2024-11-19 15:54:46 -07:00

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
This commit is contained in:
Russ Cox 2011-11-03 17:35:28 -04:00
parent 31452a3618
commit f437331f80
16 changed files with 130 additions and 111 deletions

View File

@ -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))\

View File

@ -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 // sec is in AX, usec in BX
MOVL AX, (DI) // convert to DX:AX nsec
MOVL $0, 4(DI) // zero extend 32 -> 64 MOVL $1000000000, CX
MULL CX
MOVL usec+4(FP), DI IMULL $1000, BX
MOVL DX, (DI) 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

View File

@ -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

View File

@ -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 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
MOVL $416, AX MOVL $416, AX
INT $0x80 INT $0x80

View File

@ -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
MOVL 16(SP), DX // usec
MOVQ 8(SP), BX // sec // sec is in AX, usec in DX
MOVQ sec+0(FP), DI // return nsec in AX
MOVQ BX, (DI) IMULQ $1000000000, AX
IMULQ $1000, DX
MOVL 16(SP), BX // usec ADDQ DX, AX
MOVQ usec+8(FP), DI
MOVL BX, (DI)
RET RET
TEXT runtime·sigaction(SB),7,$-8 TEXT runtime·sigaction(SB),7,$-8

View File

@ -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

View File

@ -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
MOVL 16(SP), DX // usec
MOVQ 8(SP), BX // sec // sec is in AX, usec in DX
MOVQ sec+0(FP), DI // return nsec in AX
MOVQ BX, (DI) IMULQ $1000000000, AX
IMULQ $1000, DX
MOVL 16(SP), BX // usec ADDQ DX, AX
MOVQ usec+8(FP), DI
MOVL BX, (DI)
RET RET
TEXT runtime·rt_sigaction(SB),7,$0-32 TEXT runtime·rt_sigaction(SB),7,$0-32

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -4,9 +4,10 @@
#include "runtime.h" #include "runtime.h"
void int64
runtime·gettime(int64*, int32*) runtime·nanotime(void)
{ {
// Won't compile.
} }
String String

View File

@ -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)
{ {

View File

@ -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);

13
src/pkg/runtime/time.goc Normal file
View File

@ -0,0 +1,13 @@
// 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();
}

View File

@ -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;
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;
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)
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)
{ {
} }
void int64
runtime·gettime(int64 *sec, int32 *usec) runtime·nanotime(void)
{ {
int64 count; int64 filetime;
runtime·stdcall(runtime·QueryPerformanceCounter, 1, &count); runtime·stdcall(runtime·GetSystemTimeAsFileTime, 1, &filetime);
*sec = count / timerfreq;
count %= timerfreq; // Filetime is 100s of nanoseconds since January 1, 1601.
*usec = count*1000000 / timerfreq; // Convert to nanoseconds since January 1, 1970.
return (filetime - 116444736000000000LL) * 100LL;
} }
// Calling stdcall on os stack. // Calling stdcall on os stack.

View File

@ -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