go time_fake 源码

2022-07-15 浏览 (1029)

golang time_fake 代码

文件路径:/src/runtime/time_fake.go

/ Copyright 2019 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.

/go:build faketime && !windows

/ Faketime isn't currently supported on Windows. This would require
/ modifying syscall.Write to call syscall.faketimeWrite,
/ translating the Stdout and Stderr handles into FDs 1 and 2.
/ (See CL 192739 PS 3.)

package runtime

import "unsafe"

/ faketime is the simulated time in nanoseconds since 1970 for the
/ playground.
var faketime int64 = 1257894000000000000

var faketimeState struct {
	lock mutex

	/ lastfaketime is the last faketime value written to fd 1 or 2.
	lastfaketime int64

	/ lastfd is the fd to which lastfaketime was written.
	/
	/ Subsequent writes to the same fd may use the same
	/ timestamp, but the timestamp must increase if the fd
	/ changes.
	lastfd uintptr
}

/go:nosplit
func nanotime() int64 {
	return faketime
}

/go:linkname time_now time.now
func time_now() (sec int64, nsec int32, mono int64) {
	return faketime / 1e9, int32(faketime % 1e9), faketime
}

/ write is like the Unix write system call.
/ We have to avoid write barriers to avoid potential deadlock
/ on write calls.
/
/go:nowritebarrierrec
func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
	if !(fd == 1 || fd == 2) {
		/ Do an ordinary write.
		return write1(fd, p, n)
	}

	/ Write with the playback header.

	/ First, lock to avoid interleaving writes.
	lock(&faketimeState.lock)

	/ If the current fd doesn't match the fd of the previous write,
	/ ensure that the timestamp is strictly greater. That way, we can
	/ recover the original order even if we read the fds separately.
	t := faketimeState.lastfaketime
	if fd != faketimeState.lastfd {
		t++
		faketimeState.lastfd = fd
	}
	if faketime > t {
		t = faketime
	}
	faketimeState.lastfaketime = t

	/ Playback header: 0 0 P B <8-byte time> <4-byte data length> (big endian)
	var buf [4 + 8 + 4]byte
	buf[2] = 'P'
	buf[3] = 'B'
	tu := uint64(t)
	buf[4] = byte(tu >> (7 * 8))
	buf[5] = byte(tu >> (6 * 8))
	buf[6] = byte(tu >> (5 * 8))
	buf[7] = byte(tu >> (4 * 8))
	buf[8] = byte(tu >> (3 * 8))
	buf[9] = byte(tu >> (2 * 8))
	buf[10] = byte(tu >> (1 * 8))
	buf[11] = byte(tu >> (0 * 8))
	nu := uint32(n)
	buf[12] = byte(nu >> (3 * 8))
	buf[13] = byte(nu >> (2 * 8))
	buf[14] = byte(nu >> (1 * 8))
	buf[15] = byte(nu >> (0 * 8))
	write1(fd, unsafe.Pointer(&buf[0]), int32(len(buf)))

	/ Write actual data.
	res := write1(fd, p, n)

	unlock(&faketimeState.lock)
	return res
}

相关信息

go 源码目录

相关文章

go abi_test 源码

go alg 源码

go align_runtime_test 源码

go align_test 源码

go asan 源码

go asan0 源码

go atomic_pointer 源码

go auxv_none 源码

go callers_test 源码

go cgo 源码

^