text: #ifndef _LINUX_TIME32_H
  #define _LINUX_TIME32_H
  /*
   * These are all interfaces based on the old time_t definition
   * that overflows in 2038 on 32-bit architectures. New code
   * should use the replacements based on time64_t and timespec64.
   *
   * Any interfaces in here that become unused as we migrate
   * code to time64_t should get removed.
   */
  
  #include <linux/time64.h>
  
  #define TIME_T_MAX	(time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
  
  #if __BITS_PER_LONG == 64
  
  /* timespec64 is defined as timespec here */
  static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
  {
  	return *(const struct timespec *)&ts64;
  }
  
  static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
  {
  	return *(const struct timespec64 *)&ts;
  }
  
  #else
  static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
  {
  	struct timespec ret;
  
  	ret.tv_sec = (time_t)ts64.tv_sec;
  	ret.tv_nsec = ts64.tv_nsec;
  	return ret;
  }
  
  static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
  {
  	struct timespec64 ret;
  
  	ret.tv_sec = ts.tv_sec;
  	ret.tv_nsec = ts.tv_nsec;
  	return ret;
  }
  #endif
  
  static inline int timespec_equal(const struct timespec *a,
  				 const struct timespec *b)
  {
  	return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
  }
  
  /*
   * lhs < rhs:  return <0
   * lhs == rhs: return 0
   * lhs > rhs:  return >0
   */
  static inline int timespec_compare(const struct timespec *lhs, const struct timespec *rhs)
  {
  	if (lhs->tv_sec < rhs->tv_sec)
  		return -1;
  	if (lhs->tv_sec > rhs->tv_sec)
  		return 1;
  	return lhs->tv_nsec - rhs->tv_nsec;
  }
  
  extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
  
  static inline struct timespec timespec_add(struct timespec lhs,
  						struct timespec rhs)
  {
  	struct timespec ts_delta;
  
  	set_normalized_timespec(&ts_delta, lhs.tv_sec + rhs.tv_sec,
  				lhs.tv_nsec + rhs.tv_nsec);
  	return ts_delta;
  }
  
  /*
   * sub = lhs - rhs, in normalized form
   */
  static inline struct timespec timespec_sub(struct timespec lhs,
  						struct timespec rhs)
  {
  	struct timespec ts_delta;
  
  	set_normalized_timespec(&ts_delta, lhs.tv_sec - rhs.tv_sec,
  				lhs.tv_nsec - rhs.tv_nsec);
  	return ts_delta;
  }
  
  /*
   * Returns true if the timespec is norm, false if denorm:
   */
  static inline bool timespec_valid(const struct timespec *ts)
  {
  	/* Dates before 1970 are bogus */
  	if (ts->tv_sec < 0)
  		return false;
  	/* Can't have more nanoseconds then a second */
  	if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
  		return false;
  	return true;
  }
  
  static inline bool timespec_valid_strict(const struct timespec *ts)
  {
  	if (!timespec_valid(ts))
  		return false;
  	/* Disallow values that could overflow ktime_t */
  	if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
  		return false;
  	return true;
  }
  
  /**
   * timespec_to_ns - Convert timespec to nanoseconds
   * @ts:		pointer to the timespec variable to be converted
   *
   * Returns the scalar nanosecond representation of the timespec
   * parameter.
   */
  static inline s64 timespec_to_ns(const struct timespec *ts)
  {
  	return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
  }
  
  /**
   * ns_to_timespec - Convert nanoseconds to timespec
   * @nsec:	the nanoseconds value to be converted
   *
   * Returns the timespec representation of the nsec parameter.
   */
  extern struct timespec ns_to_timespec(const s64 nsec);
  
  /**
   * timespec_add_ns - Adds nanoseconds to a timespec
   * @a:		pointer to timespec to be incremented
   * @ns:		unsigned nanoseconds value to be added
   *
   * This must always be inlined because its used from the x86-64 vdso,
   * which cannot call other kernel functions.
   */
  static __always_inline void timespec_add_ns(struct timespec *a, u64 ns)
  {
  	a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
  	a->tv_nsec = ns;
  }
  
  /**
   * time_to_tm - converts the calendar time to local broken-down time
   *
   * @totalsecs	the number of seconds elapsed since 00:00:00 on January 1, 1970,
   *		Coordinated Universal Time (UTC).
   * @offset	offset seconds adding to totalsecs.
   * @result	pointer to struct tm variable to receive broken-down time
   */
  static inline void time_to_tm(time_t totalsecs, int offset, struct tm *result)
  {
  	time64_to_tm(totalsecs, offset, result);
  }
  
  static inline unsigned long mktime(const unsigned int year,
  			const unsigned int mon, const unsigned int day,
  			const unsigned int hour, const unsigned int min,
  			const unsigned int sec)
  {
  	return mktime64(year, mon, day, hour, min, sec);
  }
  
  static inline bool timeval_valid(const struct timeval *tv)
  {
  	/* Dates before 1970 are bogus */
  	if (tv->tv_sec < 0)
  		return false;
  
  	/* Can't have more microseconds then a second */
  	if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
  		return false;
  
  	return true;
  }
  
  extern struct timespec timespec_trunc(struct timespec t, unsigned int gran);
  
  /**
   * timeval_to_ns - Convert timeval to nanoseconds
   * @ts:		pointer to the timeval variable to be converted
   *
   * Returns the scalar nanosecond representation of the timeval
   * parameter.
   */
  static inline s64 timeval_to_ns(const struct timeval *tv)
  {
  	return ((s64) tv->tv_sec * NSEC_PER_SEC) +
  		tv->tv_usec * NSEC_PER_USEC;
  }
  
  /**
   * ns_to_timeval - Convert nanoseconds to timeval
   * @nsec:	the nanoseconds value to be converted
   *
   * Returns the timeval representation of the nsec parameter.
   */
  extern struct timeval ns_to_timeval(const s64 nsec);
  extern struct __kernel_old_timeval ns_to_kernel_old_timeval(s64 nsec);
  
  /*
   * New aliases for compat time functions. These will be used to replace
   * the compat code so it can be shared between 32-bit and 64-bit builds
   * both of which provide compatibility with old 32-bit tasks.
   */
  #define old_time32_t		compat_time_t
  #define old_timeval32		compat_timeval
  #define old_timespec32		compat_timespec
  #define old_itimerspec32	compat_itimerspec
  #define ns_to_old_timeval32	ns_to_compat_timeval
  #define get_old_itimerspec32	get_compat_itimerspec64
  #define put_old_itimerspec32	put_compat_itimerspec64
  #define get_old_timespec32	compat_get_timespec64
  #define put_old_timespec32	compat_put_timespec64
  
  #endif
  