github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/pkg/abi/linux/time.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package linux 16 17 import ( 18 "math" 19 "time" 20 ) 21 22 const ( 23 // ClockTick is the length of time represented by a single clock tick, as 24 // used by times(2) and /proc/[pid]/stat. 25 ClockTick = time.Second / CLOCKS_PER_SEC 26 27 // CLOCKS_PER_SEC is the number of ClockTicks per second. 28 // 29 // Linux defines this to be 100 on most architectures, irrespective of 30 // CONFIG_HZ. Userspace obtains the value through sysconf(_SC_CLK_TCK), 31 // which uses the AT_CLKTCK entry in the auxiliary vector if one is 32 // provided, and assumes 100 otherwise (glibc: 33 // sysdeps/posix/sysconf.c:__sysconf() => 34 // sysdeps/unix/sysv/linux/getclktck.c, elf/dl-support.c:_dl_aux_init()). 35 // 36 // Not to be confused with POSIX CLOCKS_PER_SEC, as used by clock(3); "XSI 37 // requires that [POSIX] CLOCKS_PER_SEC equals 1000000 independent of the 38 // actual resolution" - clock(3). 39 CLOCKS_PER_SEC = 100 40 ) 41 42 // CPU clock types for use with clock_gettime(2) et al. 43 // 44 // The 29 most significant bits of a 32 bit clock ID are either a PID or a FD. 45 // 46 // Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3. 47 // 48 // Bit 2 indicates whether a cpu clock refers to a thread or a process. 49 const ( 50 CPUCLOCK_PROF = 0 51 CPUCLOCK_VIRT = 1 52 CPUCLOCK_SCHED = 2 53 CPUCLOCK_MAX = 3 54 CLOCKFD = CPUCLOCK_MAX 55 56 CPUCLOCK_CLOCK_MASK = 3 57 CPUCLOCK_PERTHREAD_MASK = 4 58 ) 59 60 // Clock identifiers for use with clock_gettime(2), clock_getres(2), 61 // clock_nanosleep(2). 62 const ( 63 CLOCK_REALTIME = 0 64 CLOCK_MONOTONIC = 1 65 CLOCK_PROCESS_CPUTIME_ID = 2 66 CLOCK_THREAD_CPUTIME_ID = 3 67 CLOCK_MONOTONIC_RAW = 4 68 CLOCK_REALTIME_COARSE = 5 69 CLOCK_MONOTONIC_COARSE = 6 70 CLOCK_BOOTTIME = 7 71 CLOCK_REALTIME_ALARM = 8 72 CLOCK_BOOTTIME_ALARM = 9 73 ) 74 75 // Flags for clock_nanosleep(2). 76 const ( 77 TIMER_ABSTIME = 1 78 ) 79 80 // Flags for timerfd syscalls (timerfd_create(2), timerfd_settime(2)). 81 const ( 82 // TFD_CLOEXEC is a timerfd_create flag. 83 TFD_CLOEXEC = O_CLOEXEC 84 85 // TFD_NONBLOCK is a timerfd_create flag. 86 TFD_NONBLOCK = O_NONBLOCK 87 88 // TFD_TIMER_ABSTIME is a timerfd_settime flag. 89 TFD_TIMER_ABSTIME = 1 90 ) 91 92 // The safe number of seconds you can represent by int64. 93 const maxSecInDuration = math.MaxInt64 / int64(time.Second) 94 95 // TimeT represents time_t in <time.h>. It represents time in seconds. 96 // 97 // +marshal 98 type TimeT int64 99 100 // NsecToTimeT translates nanoseconds to TimeT (seconds). 101 func NsecToTimeT(nsec int64) TimeT { 102 return TimeT(nsec / 1e9) 103 } 104 105 // Timespec represents struct timespec in <time.h>. 106 // 107 // +marshal slice:TimespecSlice 108 type Timespec struct { 109 Sec int64 110 Nsec int64 111 } 112 113 // Unix returns the second and nanosecond. 114 func (ts Timespec) Unix() (sec int64, nsec int64) { 115 return int64(ts.Sec), int64(ts.Nsec) 116 } 117 118 // ToTime returns the Go time.Time representation. 119 func (ts Timespec) ToTime() time.Time { 120 return time.Unix(ts.Sec, ts.Nsec) 121 } 122 123 // ToNsec returns the nanosecond representation. 124 func (ts Timespec) ToNsec() int64 { 125 return int64(ts.Sec)*1e9 + int64(ts.Nsec) 126 } 127 128 // ToNsecCapped returns the safe nanosecond representation. 129 func (ts Timespec) ToNsecCapped() int64 { 130 if ts.Sec > maxSecInDuration { 131 return math.MaxInt64 132 } 133 return ts.ToNsec() 134 } 135 136 // ToDuration returns the safe nanosecond representation as time.Duration. 137 func (ts Timespec) ToDuration() time.Duration { 138 return time.Duration(ts.ToNsecCapped()) 139 } 140 141 // Valid returns whether the timespec contains valid values. 142 func (ts Timespec) Valid() bool { 143 return !(ts.Sec < 0 || ts.Nsec < 0 || ts.Nsec >= int64(time.Second)) 144 } 145 146 // NsecToTimespec translates nanoseconds to Timespec. 147 func NsecToTimespec(nsec int64) (ts Timespec) { 148 ts.Sec = nsec / 1e9 149 ts.Nsec = nsec % 1e9 150 return 151 } 152 153 // DurationToTimespec translates time.Duration to Timespec. 154 func DurationToTimespec(dur time.Duration) Timespec { 155 return NsecToTimespec(dur.Nanoseconds()) 156 } 157 158 // SizeOfTimeval is the size of a Timeval struct in bytes. 159 const SizeOfTimeval = 16 160 161 // Timeval represents struct timeval in <time.h>. 162 // 163 // +marshal slice:TimevalSlice 164 type Timeval struct { 165 Sec int64 166 Usec int64 167 } 168 169 // ToNsecCapped returns the safe nanosecond representation. 170 func (tv Timeval) ToNsecCapped() int64 { 171 if tv.Sec > maxSecInDuration { 172 return math.MaxInt64 173 } 174 return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 175 } 176 177 // ToDuration returns the safe nanosecond representation as a time.Duration. 178 func (tv Timeval) ToDuration() time.Duration { 179 return time.Duration(tv.ToNsecCapped()) 180 } 181 182 // ToTime returns the Go time.Time representation. 183 func (tv Timeval) ToTime() time.Time { 184 return time.Unix(tv.Sec, tv.Usec*1e3) 185 } 186 187 // NsecToTimeval translates nanosecond to Timeval. 188 func NsecToTimeval(nsec int64) (tv Timeval) { 189 nsec += 999 // round up to microsecond 190 tv.Sec = nsec / 1e9 191 tv.Usec = nsec % 1e9 / 1e3 192 return 193 } 194 195 // DurationToTimeval translates time.Duration to Timeval. 196 func DurationToTimeval(dur time.Duration) Timeval { 197 return NsecToTimeval(dur.Nanoseconds()) 198 } 199 200 // Itimerspec represents struct itimerspec in <time.h>. 201 // 202 // +marshal 203 type Itimerspec struct { 204 Interval Timespec 205 Value Timespec 206 } 207 208 // ItimerVal mimics the following struct in <sys/time.h> 209 // 210 // struct itimerval { 211 // struct timeval it_interval; /* next value */ 212 // struct timeval it_value; /* current value */ 213 // }; 214 // 215 // +marshal 216 type ItimerVal struct { 217 Interval Timeval 218 Value Timeval 219 } 220 221 // ClockT represents type clock_t. 222 // 223 // +marshal 224 type ClockT int64 225 226 // ClockTFromDuration converts time.Duration to clock_t. 227 func ClockTFromDuration(d time.Duration) ClockT { 228 return ClockT(d / ClockTick) 229 } 230 231 // Tms represents struct tms, used by times(2). 232 // 233 // +marshal 234 type Tms struct { 235 UTime ClockT 236 STime ClockT 237 CUTime ClockT 238 CSTime ClockT 239 } 240 241 // TimerID represents type timer_t, which identifies a POSIX per-process 242 // interval timer. 243 // 244 // +marshal 245 type TimerID int32 246 247 // StatxTimestamp represents struct statx_timestamp. 248 // 249 // +marshal 250 type StatxTimestamp struct { 251 Sec int64 252 Nsec uint32 253 _ int32 254 } 255 256 // ToNsec returns the nanosecond representation. 257 func (sxts StatxTimestamp) ToNsec() int64 { 258 return int64(sxts.Sec)*1e9 + int64(sxts.Nsec) 259 } 260 261 // ToNsecCapped returns the safe nanosecond representation. 262 func (sxts StatxTimestamp) ToNsecCapped() int64 { 263 if sxts.Sec > maxSecInDuration { 264 return math.MaxInt64 265 } 266 return sxts.ToNsec() 267 } 268 269 // NsecToStatxTimestamp translates nanoseconds to StatxTimestamp. 270 func NsecToStatxTimestamp(nsec int64) (ts StatxTimestamp) { 271 return StatxTimestamp{ 272 Sec: nsec / 1e9, 273 Nsec: uint32(nsec % 1e9), 274 } 275 } 276 277 // ToTime returns the Go time.Time representation. 278 func (sxts StatxTimestamp) ToTime() time.Time { 279 return time.Unix(sxts.Sec, int64(sxts.Nsec)) 280 } 281 282 // Utime represents struct utimbuf used by utimes(2). 283 // 284 // +marshal 285 type Utime struct { 286 Actime int64 287 Modtime int64 288 }