github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/session/mbtime/mbtime.go (about) 1 /* 2 * Copyright (C) 2020 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package mbtime 19 20 import ( 21 "syscall" 22 "time" 23 24 // Needed for go:linkname 25 _ "unsafe" 26 27 "github.com/rs/zerolog/log" 28 ) 29 30 // Time represents structure for calculating elapsed duration between time interval. 31 // It uses different syscalls depending on platform expect for Windows it uses std 32 // library time since it already includes boottime. 33 type Time struct { 34 // ns represents suspend-aware monotonic clock time in nanoseconds. 35 ns time.Duration 36 } 37 38 // Now returns current suspend-aware monotonic time. 39 func Now() Time { 40 ts, err := nanotime() 41 if err != nil { 42 log.Error().Err(err).Msgf("Using fallback time") 43 return Time{ns: time.Duration(nanotimeFallback())} 44 } 45 return Time{ns: time.Duration(ts)} 46 } 47 48 // New creates new suspend-aware monotonic time from given initial values. 49 // This is mostly useful for unit tests. 50 func New(sec int64, nsec int64) Time { 51 return Time{ns: time.Duration(sec*1e9 + nsec)} 52 } 53 54 // Nano returns current duration in nanoseconds. 55 func (t Time) Nano() time.Duration { 56 return t.ns 57 } 58 59 const ( 60 minDuration time.Duration = -1 << 63 61 maxDuration time.Duration = 1<<63 - 1 62 ) 63 64 // Sub returns the duration t-u. 65 func (t Time) Sub(u Time) time.Duration { 66 d := t.ns - u.ns 67 if d < 0 && t.ns > u.ns { 68 return maxDuration // t - u is positive out of range 69 } 70 if d > 0 && t.ns < u.ns { 71 return minDuration // t - u is negative out of range 72 } 73 return d 74 } 75 76 // String returns time formatted time string. 77 func (t Time) String() string { 78 return t.ns.String() 79 } 80 81 // Since returns the time elapsed since t. 82 // It is shorthand for time.Now().Sub(t). 83 func Since(u Time) time.Duration { 84 return Now().ns - u.ns 85 } 86 87 func tempSyscallErr(err error) bool { 88 errno, ok := err.(syscall.Errno) 89 if !ok { 90 return false 91 } 92 return errno.Temporary() 93 } 94 95 //go:noescape 96 //go:linkname nanotimeFallback runtime.nanotime 97 func nanotimeFallback() int64