github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/time_fake.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build faketime && !windows 6 // +build faketime,!windows 7 8 // Faketime isn't currently supported on Windows. This would require 9 // modifying syscall.Write to call syscall.faketimeWrite, 10 // translating the Stdout and Stderr handles into FDs 1 and 2. 11 // (See CL 192739 PS 3.) 12 13 package runtime 14 15 import "unsafe" 16 17 // faketime is the simulated time in nanoseconds since 1970 for the 18 // playground. 19 var faketime int64 = 1257894000000000000 20 21 var faketimeState struct { 22 lock mutex 23 24 // lastfaketime is the last faketime value written to fd 1 or 2. 25 lastfaketime int64 26 27 // lastfd is the fd to which lastfaketime was written. 28 // 29 // Subsequent writes to the same fd may use the same 30 // timestamp, but the timestamp must increase if the fd 31 // changes. 32 lastfd uintptr 33 } 34 35 //go:nosplit 36 func nanotime() int64 { 37 return faketime 38 } 39 40 //go:linkname time_now time.now 41 func time_now() (sec int64, nsec int32, mono int64) { 42 return faketime / 1e9, int32(faketime % 1e9), faketime 43 } 44 45 func write(fd uintptr, p unsafe.Pointer, n int32) int32 { 46 if !(fd == 1 || fd == 2) { 47 // Do an ordinary write. 48 return write1(fd, p, n) 49 } 50 51 // Write with the playback header. 52 53 // First, lock to avoid interleaving writes. 54 lock(&faketimeState.lock) 55 56 // If the current fd doesn't match the fd of the previous write, 57 // ensure that the timestamp is strictly greater. That way, we can 58 // recover the original order even if we read the fds separately. 59 t := faketimeState.lastfaketime 60 if fd != faketimeState.lastfd { 61 t++ 62 faketimeState.lastfd = fd 63 } 64 if faketime > t { 65 t = faketime 66 } 67 faketimeState.lastfaketime = t 68 69 // Playback header: 0 0 P B <8-byte time> <4-byte data length> (big endian) 70 var buf [4 + 8 + 4]byte 71 buf[2] = 'P' 72 buf[3] = 'B' 73 tu := uint64(t) 74 buf[4] = byte(tu >> (7 * 8)) 75 buf[5] = byte(tu >> (6 * 8)) 76 buf[6] = byte(tu >> (5 * 8)) 77 buf[7] = byte(tu >> (4 * 8)) 78 buf[8] = byte(tu >> (3 * 8)) 79 buf[9] = byte(tu >> (2 * 8)) 80 buf[10] = byte(tu >> (1 * 8)) 81 buf[11] = byte(tu >> (0 * 8)) 82 nu := uint32(n) 83 buf[12] = byte(nu >> (3 * 8)) 84 buf[13] = byte(nu >> (2 * 8)) 85 buf[14] = byte(nu >> (1 * 8)) 86 buf[15] = byte(nu >> (0 * 8)) 87 write1(fd, unsafe.Pointer(&buf[0]), int32(len(buf))) 88 89 // Write actual data. 90 res := write1(fd, p, n) 91 92 unlock(&faketimeState.lock) 93 return res 94 }