Commit 350a8fcd authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: make MemStats.LastGC Unix time again

The monotonic clock patch changed all runtime times
to abstract monotonic time. As the result user-visible
MemStats.LastGC become monotonic time as well.
Restore Unix time for LastGC.

This is the simplest way to expose time.now to runtime that I found.
Another option would be to change time.now to C called
int64 runtime.unixnanotime() and then express time.now in terms of it.
But this would require to introduce 2 64-bit divisions into time.now.
Another option would be to change time.now to C called
void runtime.unixnanotime1(struct {int64 sec, int32 nsec} *now)
and then express both time.now and runtime.unixnanotime in terms of it.

Fixes #7852.

LGTM=minux.ma, iant
R=minux.ma, rsc, iant
CC=golang-codereviews
https://golang.org/cl/93720045
parent 3879f0ab
......@@ -2146,3 +2146,6 @@ TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
ADDL $4,DI
RET
TEXT runtime·timenow(SB), NOSPLIT, $0-0
JMP time·now(SB)
......@@ -2179,3 +2179,6 @@ TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
ADDQ $8,DI
RET
TEXT runtime·timenow(SB), NOSPLIT, $0-0
JMP time·now(SB)
......@@ -1064,3 +1064,6 @@ TEXT bytes·Equal(SB),NOSPLIT,$0-25
eqret:
MOVB AX, ret+24(FP)
RET
TEXT runtime·timenow(SB), NOSPLIT, $0-0
JMP time·now(SB)
......@@ -747,3 +747,6 @@ _sib_notfound:
MOVW $-1, R0
MOVW R0, ret+12(FP)
RET
TEXT runtime·timenow(SB), NOSPLIT, $0-0
B time·now(SB)
......@@ -9,6 +9,7 @@ import (
"runtime"
"runtime/debug"
"testing"
"time"
)
func TestGcSys(t *testing.T) {
......@@ -152,6 +153,18 @@ func TestGcRescan(t *testing.T) {
}
}
func TestGcLastTime(t *testing.T) {
ms := new(runtime.MemStats)
t0 := time.Now().UnixNano()
runtime.GC()
t1 := time.Now().UnixNano()
runtime.ReadMemStats(ms)
last := int64(ms.LastGC)
if t0 > last || last > t1 {
t.Fatalf("bad last GC time: got %v, want [%v, %v]", last, t0, t1)
}
}
func BenchmarkSetTypeNoPtr1(b *testing.B) {
type NoPtr1 struct {
p uintptr
......
......@@ -91,6 +91,8 @@ enum {
// Initialized from $GOGC. GOGC=off means no gc.
static int32 gcpercent = GcpercentUnknown;
void runtime·gc_unixnanotime(int64 *now);
static FuncVal* poolcleanup;
void
......@@ -2404,7 +2406,7 @@ gc(struct gc_args *args)
mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*gcpercent/100;
t4 = runtime·nanotime();
mstats.last_gc = t4;
runtime·gc_unixnanotime((int64*)&mstats.last_gc); // must be Unix time to make sense to user
mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t4 - t0;
mstats.pause_total_ns += t4 - t0;
mstats.numgc++;
......
......@@ -18,3 +18,10 @@ func gc_g_ptr(ret *interface{}) {
func gc_itab_ptr(ret *interface{}) {
*ret = (*itab)(nil)
}
func timenow() (sec int64, nsec int32)
func gc_unixnanotime(now *int64) {
sec, nsec := timenow()
*now = sec*1e9 + int64(nsec)
}
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