]> Cypherpunks repositories - gostls13.git/commitdiff
time: faster Nanoseconds call
authorRuss Cox <rsc@golang.org>
Thu, 3 Nov 2011 21:35:28 +0000 (17:35 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 3 Nov 2011 21:35:28 +0000 (17:35 -0400)
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

16 files changed:
src/pkg/runtime/Makefile
src/pkg/runtime/darwin/386/sys.s
src/pkg/runtime/darwin/amd64/sys.s
src/pkg/runtime/freebsd/386/sys.s
src/pkg/runtime/freebsd/amd64/sys.s
src/pkg/runtime/linux/386/sys.s
src/pkg/runtime/linux/amd64/sys.s
src/pkg/runtime/linux/arm/sys.s
src/pkg/runtime/openbsd/386/sys.s
src/pkg/runtime/openbsd/amd64/sys.s
src/pkg/runtime/plan9/386/signal.c
src/pkg/runtime/runtime.c
src/pkg/runtime/runtime.h
src/pkg/runtime/time.goc [new file with mode: 0644]
src/pkg/runtime/windows/thread.c
src/pkg/time/sys.go

index 2d7b51b894cb66b315cb82b8b516fe16705a065b..40150d2f6833b28af745c711f0b25cd7f5f6e09e 100644 (file)
@@ -98,6 +98,7 @@ OFILES=\
        symtab.$O\
        sys.$O\
        thread.$O\
+       time.$O\
        traceback.$O\
        $(OFILES_$(GOARCH))\
        $(OFILES_$(GOOS))\
index 15eaf93bc3e8a722265dd94576f2db5581c88134..c8b89bfa3f43612a1f874c33173c49176759601f 100644 (file)
@@ -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
index 7c79f18c49aa6929509d326a67d3951700783d8c..f049d973db82cedbc4c372cb995cef530eb2f091 100644 (file)
@@ -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
index 4c0b4e41a11dc30a70e92ddad58f1ff88e3cbd4e..3856a53707f9b4f87a86659c19f7d38774368635 100644 (file)
@@ -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
index e973b520cf740410ac2e46071cb4a3b89f171884..252069e0db77d9db9c87390a130b8fcce7a33626 100644 (file)
@@ -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
index 1b4f649bd73f6561e36673ebc5a319929b160c3c..97d9d5ed9cb6f96286bad47b6f5843468e0d5857 100644 (file)
@@ -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
index 3174af2cb0599f23bfe3ae609202f414e41365b8..227c8e62cce2d7f47b105ed6ce73759821abd308 100644 (file)
@@ -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
index 764e779fdd3e448e7ddea7c9eb30504ecf9062a1..45da858abda09db1a04ebe2e96fb953943d19fde 100644 (file)
@@ -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
index d2df51827648d46ea67dec396724cc6e14e34a04..6a6a7bbd3be29671273910bd253196f47b899d21 100644 (file)
@@ -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
index 29d74a1200d7236c9d18b1d8ce16b4f525aa1734..dfbb2547fafebf5ca43fe665006cc238c68d23ac 100644 (file)
@@ -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
index 364fd1c4187fed9830ad2ae119ce2fa715ed19ec..77e40d35a96c7cebf5103a3b34c35116e9f88458 100644 (file)
@@ -4,9 +4,10 @@
 
 #include "runtime.h"
 
-void
-runtime·gettime(int64*, int32*
+int64
+runtime·nanotime(void
 {
+       // Won't compile.
 }
 
 String
index ae6fd877c7014e78254e74e2a772b72599d75ff9..a82e8b6b4908685939c103b4c889a3c93b6dbecc 100644 (file)
@@ -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)
 {
index 685725a41c72ff221bd3b4ebaff36efc072dfbe1..da80b99eb8f172abfa2f53cb44e3e393ed0d3a76 100644 (file)
@@ -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);
diff --git a/src/pkg/runtime/time.goc b/src/pkg/runtime/time.goc
new file mode 100644 (file)
index 0000000..a620f2b
--- /dev/null
@@ -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();
+}
index 0498c76af1faa50e12b0ee96389d0c77cb19dd9b..c00485b1a8e712d8ab06258d9131c93554c0514c 100644 (file)
 #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.
index 4bc925339361ccbc382b2a8c1f2ff73266cbd663..ca1d334a5b7aafa87d61bb322f070e012ec2ec0d 100644 (file)
@@ -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