github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/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  }