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=\
symtab.$O\
sys.$O\
thread.$O\
time.$O\
traceback.$O\
$(OFILES_$(GOARCH))\
$(OFILES_$(GOOS))\
......
......@@ -60,20 +60,27 @@ TEXT runtime·setitimer(SB),7,$0
INT $0x80
RET
// void gettime(int64 *sec, int32 *usec)
TEXT runtime·gettime(SB), 7, $32
// int64 nanotime(void) so really
// void nanotime(int64 *nsec)
TEXT runtime·nanotime(SB), 7, $32
LEAL 12(SP), AX // must be non-nil, unused
MOVL AX, 4(SP)
MOVL $0, 8(SP) // time zone pointer
MOVL $116, AX
INT $0x80
MOVL sec+0(FP), DI
MOVL AX, (DI)
MOVL $0, 4(DI) // zero extend 32 -> 64
MOVL usec+4(FP), DI
MOVL DX, (DI)
MOVL DX, BX
// 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
TEXT runtime·sigaction(SB),7,$0
......
......@@ -55,16 +55,18 @@ TEXT runtime·setitimer(SB), 7, $0
SYSCALL
RET
// void gettime(int64 *sec, int32 *usec)
TEXT runtime·gettime(SB), 7, $32
// int64 nanotime(void)
TEXT runtime·nanotime(SB), 7, $32
MOVQ SP, DI // must be non-nil, unused
MOVQ $0, SI
MOVL $(0x2000000+116), AX
SYSCALL
MOVQ sec+0(FP), DI
MOVQ AX, (DI)
MOVQ usec+8(FP), DI
MOVL DX, (DI)
// sec is in AX, usec in DX
// return nsec in AX
IMULQ $1000000000, AX
IMULQ $1000, DX
ADDQ DX, AX
RET
TEXT runtime·sigaction(SB),7,$0
......
......@@ -106,23 +106,31 @@ TEXT runtime·setitimer(SB), 7, $-4
INT $0x80
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
LEAL 12(SP), BX
MOVL BX, 4(SP)
MOVL $0, 8(SP)
INT $0x80
MOVL 12(SP), BX // sec
MOVL sec+0(FP), DI
MOVL BX, (DI)
MOVL $0, 4(DI) // zero extend 32 -> 64 bits
MOVL 12(SP), AX // sec
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
TEXT runtime·sigaction(SB),7,$-4
MOVL $416, AX
INT $0x80
......
......@@ -85,19 +85,19 @@ TEXT runtime·setitimer(SB), 7, $-8
SYSCALL
RET
TEXT runtime·gettime(SB), 7, $32
TEXT runtime·nanotime(SB), 7, $32
MOVL $116, AX
LEAQ 8(SP), DI
MOVQ $0, SI
SYSCALL
MOVQ 8(SP), BX // sec
MOVQ sec+0(FP), DI
MOVQ BX, (DI)
MOVL 16(SP), BX // usec
MOVQ usec+8(FP), DI
MOVL BX, (DI)
MOVQ 8(SP), AX // sec
MOVL 16(SP), DX // usec
// sec is in AX, usec in DX
// return nsec in AX
IMULQ $1000000000, AX
IMULQ $1000, DX
ADDQ DX, AX
RET
TEXT runtime·sigaction(SB),7,$-8
......
......@@ -95,21 +95,28 @@ TEXT runtime·mincore(SB),7,$0-24
CALL *runtime·_vdso(SB)
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
LEAL 8(SP), BX
MOVL $0, CX
MOVL $0, DX
CALL *runtime·_vdso(SB)
MOVL 8(SP), BX // sec
MOVL sec+0(FP), DI
MOVL BX, (DI)
MOVL $0, 4(DI) // zero extend 32 -> 64 bits
MOVL 8(SP), AX // sec
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
TEXT runtime·rt_sigaction(SB),7,$0
......
......@@ -93,19 +93,19 @@ TEXT runtime·mincore(SB),7,$0-24
SYSCALL
RET
TEXT runtime·gettime(SB), 7, $32
TEXT runtime·nanotime(SB), 7, $32
LEAQ 8(SP), DI
MOVQ $0, SI
MOVQ $0xffffffffff600000, AX
CALL AX
MOVQ 8(SP), BX // sec
MOVQ sec+0(FP), DI
MOVQ BX, (DI)
MOVL 16(SP), BX // usec
MOVQ usec+8(FP), DI
MOVL BX, (DI)
MOVQ 8(SP), AX // sec
MOVL 16(SP), DX // usec
// sec is in AX, usec in DX
// return nsec in AX
IMULQ $1000000000, AX
IMULQ $1000, DX
ADDQ DX, AX
RET
TEXT runtime·rt_sigaction(SB),7,$0-32
......
......@@ -127,14 +127,14 @@ TEXT runtime·mincore(SB),7,$0
SWI $0
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 */
MOVW $0, R1
MOVW 0(FP), R0
MOVW R1, 0(R0)
MOVW R1, 4(R0)
MOVW 4(FP), R0
MOVW R1, 0(R0)
/*
attempt at real version - seg faults
......
......@@ -91,21 +91,28 @@ TEXT runtime·setitimer(SB),7,$-4
INT $0x80
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
LEAL 12(SP), BX
MOVL BX, 4(SP)
MOVL $0, 8(SP)
INT $0x80
MOVL 12(SP), BX // sec
MOVL sec+0(FP), DI
MOVL BX, (DI)
MOVL $0, 4(DI) // zero extend 32 -> 64 bits
MOVL 12(SP), AX // sec
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
TEXT runtime·sigaction(SB),7,$-4
......
......@@ -133,19 +133,19 @@ TEXT runtime·setitimer(SB),7,$-8
SYSCALL
RET
TEXT runtime·gettime(SB),7,$32
TEXT runtime·nanotime(SB),7,$32
LEAQ 8(SP), DI // arg 1 - tp
MOVQ $0, SI // arg 2 - tzp
MOVL $116, AX // sys_gettimeofday
SYSCALL
MOVQ 8(SP), BX // sec
MOVQ sec+0(FP), DI
MOVQ BX, (DI)
MOVQ 8(SP), AX // sec
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
TEXT runtime·sigaction(SB),7,$-8
......
......@@ -4,9 +4,10 @@
#include "runtime.h"
void
runtime·gettime(int64*, int32*)
int64
runtime·nanotime(void)
{
// Won't compile.
}
String
......
......@@ -654,18 +654,6 @@ runtime·algarray[] =
[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
runtime·Caller(int32 skip, uintptr retpc, String retfile, int32 retline, bool retbool)
{
......
......@@ -490,7 +490,6 @@ void runtime·exitsyscall(void);
G* runtime·newproc1(byte*, byte*, int32, int32, void*);
void runtime·siginit(void);
bool runtime·sigsend(int32 sig);
void runtime·gettime(int64*, int32*);
int32 runtime·callers(int32, uintptr*, int32);
int32 runtime·gentraceback(byte*, byte*, byte*, G*, int32, uintptr*, int32);
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 @@
#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
#pragma dynimport runtime·GetStdHandle GetStdHandle "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·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·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
......@@ -44,10 +43,9 @@ extern void *runtime·GetEnvironmentStringsW;
extern void *runtime·GetProcAddress;
extern void *runtime·GetStdHandle;
extern void *runtime·GetSystemInfo;
extern void *runtime·GetSystemTimeAsFileTime;
extern void *runtime·GetThreadContext;
extern void *runtime·LoadLibrary;
extern void *runtime·QueryPerformanceCounter;
extern void *runtime·QueryPerformanceFrequency;
extern void *runtime·ResumeThread;
extern void *runtime·SetConsoleCtrlHandler;
extern void *runtime·SetEvent;
......@@ -59,8 +57,6 @@ extern void *runtime·timeBeginPeriod;
extern void *runtime·WaitForSingleObject;
extern void *runtime·WriteFile;
static int64 timerfreq;
static int32
getproccount(void)
{
......@@ -77,7 +73,6 @@ runtime·osinit(void)
runtime·stdcall(runtime·DuplicateHandle, 7,
(uintptr)-1, (uintptr)-2, (uintptr)-1, &m->thread,
(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·timeBeginPeriod, 1, (uintptr)1);
runtime·ncpu = getproccount();
......@@ -197,15 +192,16 @@ runtime·minit(void)
{
}
void
runtime·gettime(int64 *sec, int32 *usec)
int64
runtime·nanotime(void)
{
int64 count;
int64 filetime;
runtime·stdcall(runtime·QueryPerformanceCounter, 1, &count);
*sec = count / timerfreq;
count %= timerfreq;
*usec = count*1000000 / timerfreq;
runtime·stdcall(runtime·GetSystemTimeAsFileTime, 1, &filetime);
// Filetime is 100s of nanoseconds since January 1, 1601.
// Convert to nanoseconds since January 1, 1970.
return (filetime - 116444736000000000LL) * 100LL;
}
// Calling stdcall on os stack.
......
......@@ -4,27 +4,17 @@
package time
import "os"
// Seconds reports the number of seconds since the Unix epoch,
// January 1, 1970 00:00:00 UTC.
func Seconds() int64 {
sec, _, err := os.Time()
if err != nil {
panic(err)
}
return sec
return Nanoseconds() / 1e9
}
// Nanoseconds is implemented by package runtime.
// Nanoseconds reports the number of nanoseconds since the Unix epoch,
// January 1, 1970 00:00:00 UTC.
func Nanoseconds() int64 {
sec, nsec, err := os.Time()
if err != nil {
panic(err)
}
return sec*1e9 + nsec
}
func Nanoseconds() int64
// Sleep pauses the current goroutine for at least ns nanoseconds.
// 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