2  * Copyright (c) 2000-2008 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  28 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 
  30  * Copyright (c) 1982, 1986, 1989, 1993 
  31  *      The Regents of the University of California.  All rights reserved. 
  33  * Redistribution and use in source and binary forms, with or without 
  34  * modification, are permitted provided that the following conditions 
  36  * 1. Redistributions of source code must retain the above copyright 
  37  *    notice, this list of conditions and the following disclaimer. 
  38  * 2. Redistributions in binary form must reproduce the above copyright 
  39  *    notice, this list of conditions and the following disclaimer in the 
  40  *    documentation and/or other materials provided with the distribution. 
  41  * 3. All advertising materials mentioning features or use of this software 
  42  *    must display the following acknowledgement: 
  43  *      This product includes software developed by the University of 
  44  *      California, Berkeley and its contributors. 
  45  * 4. Neither the name of the University nor the names of its contributors 
  46  *    may be used to endorse or promote products derived from this software 
  47  *    without specific prior written permission. 
  49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  61  *      @(#)kern_time.c 8.4 (Berkeley) 5/26/95 
  64  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce 
  65  * support for mandatory and extensible security protections.  This notice 
  66  * is included in support of clause 2.2 (b) of the Apple Public License, 
  70 #include <sys/param.h> 
  71 #include <sys/resourcevar.h> 
  72 #include <sys/kernel.h> 
  73 #include <sys/systm.h> 
  74 #include <sys/proc_internal.h> 
  75 #include <sys/kauth.h> 
  76 #include <sys/vnode.h> 
  80 #include <sys/mount_internal.h> 
  81 #include <sys/sysproto.h> 
  82 #include <sys/signalvar.h> 
  83 #include <sys/protosw.h> /* for net_uptime2timeval() */ 
  85 #include <kern/clock.h> 
  86 #include <kern/task.h> 
  87 #include <kern/thread_call.h> 
  89 #include <security/mac_framework.h> 
  91 #include <IOKit/IOBSD.h> 
  93 #include <kern/remote_time.h> 
  95 #define HZ      100     /* XXX */ 
  97 /* simple lock used to access timezone, tz structure */ 
  98 lck_spin_t 
* tz_slock
; 
  99 lck_grp_t 
* tz_slock_grp
; 
 100 lck_attr_t 
* tz_slock_attr
; 
 101 lck_grp_attr_t  
*tz_slock_grp_attr
; 
 103 static void             setthetime( 
 106 void time_zone_slock_init(void); 
 107 static boolean_t 
timeval_fixusec(struct timeval 
*t1
); 
 110  * Time of day and interval timer support. 
 112  * These routines provide the kernel entry points to get and set 
 113  * the time-of-day and per-process interval timers.  Subroutines 
 114  * here provide support for adding and subtracting timeval structures 
 115  * and decrementing interval timers, optionally reloading the interval 
 116  * timers when they expire. 
 122         struct gettimeofday_args 
*uap
, 
 123         __unused 
int32_t *retval
) 
 126         struct timezone ltz
; /* local copy */ 
 131         if (uap
->tp 
|| uap
->mach_absolute_time
) { 
 132                 clock_gettimeofday_and_absolute_time(&secs
, &usecs
, &mach_time
); 
 136                 /* Casting secs through a uint32_t to match arm64 commpage */ 
 137                 if (IS_64BIT_PROCESS(p
)) { 
 138                         struct user64_timeval user_atv 
= {}; 
 139                         user_atv
.tv_sec 
= (uint32_t)secs
; 
 140                         user_atv
.tv_usec 
= usecs
; 
 141                         error 
= copyout(&user_atv
, uap
->tp
, sizeof(user_atv
)); 
 143                         struct user32_timeval user_atv 
= {}; 
 144                         user_atv
.tv_sec 
= (uint32_t)secs
; 
 145                         user_atv
.tv_usec 
= usecs
; 
 146                         error 
= copyout(&user_atv
, uap
->tp
, sizeof(user_atv
)); 
 154                 lck_spin_lock(tz_slock
); 
 156                 lck_spin_unlock(tz_slock
); 
 158                 error 
= copyout((caddr_t
)<z
, CAST_USER_ADDR_T(uap
->tzp
), sizeof(tz
)); 
 161         if (error 
== 0 && uap
->mach_absolute_time
) { 
 162                 error 
= copyout(&mach_time
, uap
->mach_absolute_time
, sizeof(mach_time
)); 
 169  * XXX Y2038 bug because of setthetime() argument 
 173 settimeofday(__unused 
struct proc 
*p
, struct settimeofday_args  
*uap
, __unused 
int32_t *retval
) 
 179         bzero(&atv
, sizeof(atv
)); 
 181         /* Check that this task is entitled to set the time or it is root */ 
 182         if (!IOTaskHasEntitlement(current_task(), SETTIME_ENTITLEMENT
)) { 
 184                 error 
= mac_system_check_settime(kauth_cred_get()); 
 189 #ifndef CONFIG_EMBEDDED 
 190                 if ((error 
= suser(kauth_cred_get(), &p
->p_acflag
))) { 
 196         /* Verify all parameters before changing time */ 
 198                 if (IS_64BIT_PROCESS(p
)) { 
 199                         struct user64_timeval user_atv
; 
 200                         error 
= copyin(uap
->tv
, &user_atv
, sizeof(user_atv
)); 
 201                         atv
.tv_sec 
= user_atv
.tv_sec
; 
 202                         atv
.tv_usec 
= user_atv
.tv_usec
; 
 204                         struct user32_timeval user_atv
; 
 205                         error 
= copyin(uap
->tv
, &user_atv
, sizeof(user_atv
)); 
 206                         atv
.tv_sec 
= user_atv
.tv_sec
; 
 207                         atv
.tv_usec 
= user_atv
.tv_usec
; 
 213         if (uap
->tzp 
&& (error 
= copyin(uap
->tzp
, (caddr_t
)&atz
, sizeof(atz
)))) { 
 217                 /* only positive values of sec/usec are accepted */ 
 218                 if (atv
.tv_sec 
< 0 || atv
.tv_usec 
< 0) { 
 221                 if (!timeval_fixusec(&atv
)) { 
 227                 lck_spin_lock(tz_slock
); 
 229                 lck_spin_unlock(tz_slock
); 
 238         clock_set_calendar_microtime(tv
->tv_sec
, tv
->tv_usec
); 
 242  *      Verify the calendar value.  If negative, 
 243  *      reset to zero (the epoch). 
 247         __unused 
time_t base
) 
 253          * The calendar has already been 
 254          * set up from the platform clock. 
 256          * The value returned by microtime() 
 257          * is gotten from the calendar. 
 261         if (tv
.tv_sec 
< 0 || tv
.tv_usec 
< 0) { 
 262                 printf("WARNING: preposterous time in Real Time Clock"); 
 263                 tv
.tv_sec 
= 0;          /* the UNIX epoch */ 
 266                 printf(" -- CHECK AND RESET THE DATE!\n"); 
 274         clock_nsec_t    nanosecs
; 
 276         clock_get_boottime_nanotime(&secs
, &nanosecs
); 
 281 boottime_timeval(struct timeval 
*tv
) 
 284         clock_usec_t    microsecs
; 
 286         clock_get_boottime_microtime(&secs
, µsecs
); 
 289         tv
->tv_usec 
= microsecs
; 
 293  * Get value of an interval timer.  The process virtual and 
 294  * profiling virtual time timers are kept internally in the 
 295  * way they are specified externally: in time until they expire. 
 297  * The real time interval timer expiration time (p_rtime) 
 298  * is kept as an absolute time rather than as a delta, so that 
 299  * it is easy to keep periodic real-time signals from drifting. 
 301  * The real time timer is processed by a callout routine. 
 302  * Since a callout may be delayed in real time due to 
 303  * other processing in the system, it is possible for the real 
 304  * time callout routine (realitexpire, given below), to be delayed 
 305  * in real time past when it is supposed to occur.  It does not 
 306  * suffice, therefore, to reload the real time .it_value from the 
 307  * real time .it_interval.  Rather, we compute the next time in 
 308  * absolute time when the timer should go off. 
 311  *              EINVAL                  Invalid argument 
 312  *      copyout:EFAULT                  Bad address 
 316 getitimer(struct proc 
*p
, struct getitimer_args 
*uap
, __unused 
int32_t *retval
) 
 318         struct itimerval aitv
; 
 320         if (uap
->which 
> ITIMER_PROF
) { 
 324         bzero(&aitv
, sizeof(aitv
)); 
 327         switch (uap
->which
) { 
 330                  * If time for real time timer has passed return 0, 
 331                  * else return difference between current time and 
 332                  * time for the timer to go off. 
 334                 aitv 
= p
->p_realtimer
; 
 335                 if (timerisset(&p
->p_rtime
)) { 
 339                         if (timercmp(&p
->p_rtime
, &now
, <)) { 
 340                                 timerclear(&aitv
.it_value
); 
 342                                 aitv
.it_value 
= p
->p_rtime
; 
 343                                 timevalsub(&aitv
.it_value
, &now
); 
 346                         timerclear(&aitv
.it_value
); 
 351                 aitv 
= p
->p_vtimer_user
; 
 355                 aitv 
= p
->p_vtimer_prof
; 
 361         if (IS_64BIT_PROCESS(p
)) { 
 362                 struct user64_itimerval user_itv
; 
 363                 bzero(&user_itv
, sizeof(user_itv
)); 
 364                 user_itv
.it_interval
.tv_sec 
= aitv
.it_interval
.tv_sec
; 
 365                 user_itv
.it_interval
.tv_usec 
= aitv
.it_interval
.tv_usec
; 
 366                 user_itv
.it_value
.tv_sec 
= aitv
.it_value
.tv_sec
; 
 367                 user_itv
.it_value
.tv_usec 
= aitv
.it_value
.tv_usec
; 
 368                 return copyout((caddr_t
)&user_itv
, uap
->itv
, sizeof(user_itv
)); 
 370                 struct user32_itimerval user_itv
; 
 371                 bzero(&user_itv
, sizeof(user_itv
)); 
 372                 user_itv
.it_interval
.tv_sec 
= aitv
.it_interval
.tv_sec
; 
 373                 user_itv
.it_interval
.tv_usec 
= aitv
.it_interval
.tv_usec
; 
 374                 user_itv
.it_value
.tv_sec 
= aitv
.it_value
.tv_sec
; 
 375                 user_itv
.it_value
.tv_usec 
= aitv
.it_value
.tv_usec
; 
 376                 return copyout((caddr_t
)&user_itv
, uap
->itv
, sizeof(user_itv
)); 
 382  *              EINVAL                  Invalid argument 
 383  *      copyin:EFAULT                   Bad address 
 384  *      getitimer:EINVAL                Invalid argument 
 385  *      getitimer:EFAULT                Bad address 
 389 setitimer(struct proc 
*p
, struct setitimer_args 
*uap
, int32_t *retval
) 
 391         struct itimerval aitv
; 
 395         bzero(&aitv
, sizeof(aitv
)); 
 397         if (uap
->which 
> ITIMER_PROF
) { 
 400         if ((itvp 
= uap
->itv
)) { 
 401                 if (IS_64BIT_PROCESS(p
)) { 
 402                         struct user64_itimerval user_itv
; 
 403                         if ((error 
= copyin(itvp
, (caddr_t
)&user_itv
, sizeof(user_itv
)))) { 
 406                         aitv
.it_interval
.tv_sec 
= user_itv
.it_interval
.tv_sec
; 
 407                         aitv
.it_interval
.tv_usec 
= user_itv
.it_interval
.tv_usec
; 
 408                         aitv
.it_value
.tv_sec 
= user_itv
.it_value
.tv_sec
; 
 409                         aitv
.it_value
.tv_usec 
= user_itv
.it_value
.tv_usec
; 
 411                         struct user32_itimerval user_itv
; 
 412                         if ((error 
= copyin(itvp
, (caddr_t
)&user_itv
, sizeof(user_itv
)))) { 
 415                         aitv
.it_interval
.tv_sec 
= user_itv
.it_interval
.tv_sec
; 
 416                         aitv
.it_interval
.tv_usec 
= user_itv
.it_interval
.tv_usec
; 
 417                         aitv
.it_value
.tv_sec 
= user_itv
.it_value
.tv_sec
; 
 418                         aitv
.it_value
.tv_usec 
= user_itv
.it_value
.tv_usec
; 
 421         if ((uap
->itv 
= uap
->oitv
) && (error 
= getitimer(p
, (struct getitimer_args 
*)uap
, retval
))) { 
 427         if (itimerfix(&aitv
.it_value
) || itimerfix(&aitv
.it_interval
)) { 
 431         switch (uap
->which
) { 
 434                 if (timerisset(&aitv
.it_value
)) { 
 435                         microuptime(&p
->p_rtime
); 
 436                         timevaladd(&p
->p_rtime
, &aitv
.it_value
); 
 437                         p
->p_realtimer 
= aitv
; 
 438                         if (!thread_call_enter_delayed_with_leeway(p
->p_rcall
, NULL
, 
 439                             tvtoabstime(&p
->p_rtime
), 0, THREAD_CALL_DELAY_USER_NORMAL
)) { 
 443                         timerclear(&p
->p_rtime
); 
 444                         p
->p_realtimer 
= aitv
; 
 445                         if (thread_call_cancel(p
->p_rcall
)) { 
 455                 if (timerisset(&aitv
.it_value
)) { 
 456                         task_vtimer_set(p
->task
, TASK_VTIMER_USER
); 
 458                         task_vtimer_clear(p
->task
, TASK_VTIMER_USER
); 
 462                 p
->p_vtimer_user 
= aitv
; 
 467                 if (timerisset(&aitv
.it_value
)) { 
 468                         task_vtimer_set(p
->task
, TASK_VTIMER_PROF
); 
 470                         task_vtimer_clear(p
->task
, TASK_VTIMER_PROF
); 
 474                 p
->p_vtimer_prof 
= aitv
; 
 483  * Real interval timer expired: 
 484  * send process whose timer expired an alarm signal. 
 485  * If time is not set up to reload, then just return. 
 486  * Else compute next time timer should go off which is > current time. 
 487  * This is where delay in processing this timeout causes multiple 
 488  * SIGALRM calls to be compressed into one. 
 497         r 
= proc_find(p
->p_pid
); 
 501         assert(p
->p_ractive 
> 0); 
 503         if (--p
->p_ractive 
> 0 || r 
!= p
) { 
 505                  * bail, because either proc is exiting 
 506                  * or there's another active thread call 
 516         if (!timerisset(&p
->p_realtimer
.it_interval
)) { 
 518                  * p_realtimer was cleared while this call was pending, 
 519                  * send one last SIGALRM, but don't re-arm 
 521                 timerclear(&p
->p_rtime
); 
 532          * Send the signal before re-arming the next thread call, 
 533          * so in case psignal blocks, we won't create yet another thread call. 
 540         /* Should we still re-arm the next thread call? */ 
 541         if (!timerisset(&p
->p_realtimer
.it_interval
)) { 
 542                 timerclear(&p
->p_rtime
); 
 550         timevaladd(&p
->p_rtime
, &p
->p_realtimer
.it_interval
); 
 552         if (timercmp(&p
->p_rtime
, &t
, <=)) { 
 553                 if ((p
->p_rtime
.tv_sec 
+ 2) >= t
.tv_sec
) { 
 555                                 timevaladd(&p
->p_rtime
, &p
->p_realtimer
.it_interval
); 
 556                                 if (timercmp(&p
->p_rtime
, &t
, >)) { 
 561                         p
->p_rtime 
= p
->p_realtimer
.it_interval
; 
 562                         timevaladd(&p
->p_rtime
, &t
); 
 566         assert(p
->p_rcall 
!= NULL
); 
 568         if (!thread_call_enter_delayed_with_leeway(p
->p_rcall
, NULL
, tvtoabstime(&p
->p_rtime
), 0, 
 569             THREAD_CALL_DELAY_USER_NORMAL
)) { 
 579  * Called once in proc_exit to clean up after an armed or pending realitexpire 
 581  * This will only be called after the proc refcount is drained, 
 582  * so realitexpire cannot be currently holding a proc ref. 
 583  * i.e. it will/has gotten PROC_NULL from proc_find. 
 586 proc_free_realitimer(proc_t p
) 
 590         assert(p
->p_rcall 
!= NULL
); 
 591         assert(p
->p_refcount 
== 0); 
 593         timerclear(&p
->p_realtimer
.it_interval
); 
 595         if (thread_call_cancel(p
->p_rcall
)) { 
 596                 assert(p
->p_ractive 
> 0); 
 600         while (p
->p_ractive 
> 0) { 
 608         thread_call_t call 
= p
->p_rcall
; 
 613         thread_call_free(call
); 
 617  * Check that a proposed value to load into the .it_value or 
 618  * .it_interval part of an interval timer is acceptable. 
 624         if (tv
->tv_sec 
< 0 || tv
->tv_sec 
> 100000000 || 
 625             tv
->tv_usec 
< 0 || tv
->tv_usec 
>= 1000000) { 
 632 timespec_is_valid(const struct timespec 
*ts
) 
 634         /* The INT32_MAX limit ensures the timespec is safe for clock_*() functions 
 635          * which accept 32-bit ints. */ 
 636         if (ts
->tv_sec 
< 0 || ts
->tv_sec 
> INT32_MAX 
|| 
 637             ts
->tv_nsec 
< 0 || (unsigned long long)ts
->tv_nsec 
> NSEC_PER_SEC
) { 
 644  * Decrement an interval timer by a specified number 
 645  * of microseconds, which must be less than a second, 
 646  * i.e. < 1000000.  If the timer expires, then reload 
 647  * it.  In this case, carry over (usec - old value) to 
 648  * reduce the value reloaded into the timer so that 
 649  * the timer does not drift.  This routine assumes 
 650  * that it is called in a context where the timers 
 651  * on which it is operating cannot change in value. 
 655     struct itimerval 
*itp
, int usec
) 
 659         if (itp
->it_value
.tv_usec 
< usec
) { 
 660                 if (itp
->it_value
.tv_sec 
== 0) { 
 661                         /* expired, and already in next interval */ 
 662                         usec 
-= itp
->it_value
.tv_usec
; 
 665                 itp
->it_value
.tv_usec 
+= 1000000; 
 666                 itp
->it_value
.tv_sec
--; 
 668         itp
->it_value
.tv_usec 
-= usec
; 
 670         if (timerisset(&itp
->it_value
)) { 
 674         /* expired, exactly at end of interval */ 
 676         if (timerisset(&itp
->it_interval
)) { 
 677                 itp
->it_value 
= itp
->it_interval
; 
 678                 if (itp
->it_value
.tv_sec 
> 0) { 
 679                         itp
->it_value
.tv_usec 
-= usec
; 
 680                         if (itp
->it_value
.tv_usec 
< 0) { 
 681                                 itp
->it_value
.tv_usec 
+= 1000000; 
 682                                 itp
->it_value
.tv_sec
--; 
 686                 itp
->it_value
.tv_usec 
= 0;              /* sec is already 0 */ 
 693  * Add and subtract routines for timevals. 
 694  * N.B.: subtract routine doesn't deal with 
 695  * results which are before the beginning, 
 696  * it just gets very confused in this case. 
 704         t1
->tv_sec 
+= t2
->tv_sec
; 
 705         t1
->tv_usec 
+= t2
->tv_usec
; 
 713         t1
->tv_sec 
-= t2
->tv_sec
; 
 714         t1
->tv_usec 
-= t2
->tv_usec
; 
 721         if (t1
->tv_usec 
< 0) { 
 723                 t1
->tv_usec 
+= 1000000; 
 725         if (t1
->tv_usec 
>= 1000000) { 
 727                 t1
->tv_usec 
-= 1000000; 
 735         assert(t1
->tv_usec 
>= 0); 
 736         assert(t1
->tv_sec 
>= 0); 
 738         if (t1
->tv_usec 
>= 1000000) { 
 739                 if (os_add_overflow(t1
->tv_sec
, t1
->tv_usec 
/ 1000000, &t1
->tv_sec
)) { 
 742                 t1
->tv_usec 
= t1
->tv_usec 
% 1000000; 
 749  * Return the best possible estimate of the time in the timeval 
 750  * to which tvp points. 
 757         clock_usec_t    tv_usec
; 
 759         clock_get_calendar_microtime(&tv_sec
, &tv_usec
); 
 761         tvp
->tv_sec 
= tv_sec
; 
 762         tvp
->tv_usec 
= tv_usec
; 
 766 microtime_with_abstime( 
 767         struct timeval  
*tvp
, uint64_t *abstime
) 
 770         clock_usec_t    tv_usec
; 
 772         clock_get_calendar_absolute_and_microtime(&tv_sec
, &tv_usec
, abstime
); 
 774         tvp
->tv_sec 
= tv_sec
; 
 775         tvp
->tv_usec 
= tv_usec
; 
 783         clock_usec_t    tv_usec
; 
 785         clock_get_system_microtime(&tv_sec
, &tv_usec
); 
 787         tvp
->tv_sec 
= tv_sec
; 
 788         tvp
->tv_usec 
= tv_usec
; 
 792  * Ditto for timespec. 
 796         struct timespec 
*tsp
) 
 799         clock_nsec_t    tv_nsec
; 
 801         clock_get_calendar_nanotime(&tv_sec
, &tv_nsec
); 
 803         tsp
->tv_sec 
= tv_sec
; 
 804         tsp
->tv_nsec 
= tv_nsec
; 
 809         struct timespec 
*tsp
) 
 812         clock_nsec_t    tv_nsec
; 
 814         clock_get_system_nanotime(&tv_sec
, &tv_nsec
); 
 816         tsp
->tv_sec 
= tv_sec
; 
 817         tsp
->tv_nsec 
= tv_nsec
; 
 824         uint64_t        result
, usresult
; 
 826         clock_interval_to_absolutetime_interval( 
 827                 tvp
->tv_sec
, NSEC_PER_SEC
, &result
); 
 828         clock_interval_to_absolutetime_interval( 
 829                 tvp
->tv_usec
, NSEC_PER_USEC
, &usresult
); 
 831         return result 
+ usresult
; 
 835 tstoabstime(struct timespec 
*ts
) 
 837         uint64_t abstime_s
, abstime_ns
; 
 838         clock_interval_to_absolutetime_interval(ts
->tv_sec
, NSEC_PER_SEC
, &abstime_s
); 
 839         clock_interval_to_absolutetime_interval(ts
->tv_nsec
, 1, &abstime_ns
); 
 840         return abstime_s 
+ abstime_ns
; 
 845  * ratecheck(): simple time-based rate-limit checking. 
 848 ratecheck(struct timeval 
*lasttime
, const struct timeval 
*mininterval
) 
 850         struct timeval tv
, delta
; 
 853         net_uptime2timeval(&tv
); 
 855         timevalsub(&delta
, lasttime
); 
 858          * check for 0,0 is so that the message will be seen at least once, 
 859          * even if interval is huge. 
 861         if (timevalcmp(&delta
, mininterval
, >=) || 
 862             (lasttime
->tv_sec 
== 0 && lasttime
->tv_usec 
== 0)) { 
 871  * ppsratecheck(): packets (or events) per second limitation. 
 874 ppsratecheck(struct timeval 
*lasttime
, int *curpps
, int maxpps
) 
 876         struct timeval tv
, delta
; 
 879         net_uptime2timeval(&tv
); 
 881         timersub(&tv
, lasttime
, &delta
); 
 884          * Check for 0,0 so that the message will be seen at least once. 
 885          * If more than one second has passed since the last update of 
 886          * lasttime, reset the counter. 
 888          * we do increment *curpps even in *curpps < maxpps case, as some may 
 889          * try to use *curpps for stat purposes as well. 
 891         if ((lasttime
->tv_sec 
== 0 && lasttime
->tv_usec 
== 0) || 
 896         } else if (maxpps 
< 0) { 
 898         } else if (*curpps 
< maxpps
) { 
 904 #if 1 /* DIAGNOSTIC? */ 
 905         /* be careful about wrap-around */ 
 906         if (*curpps 
+ 1 > 0) { 
 907                 *curpps 
= *curpps 
+ 1; 
 911          * assume that there's not too many calls to this function. 
 912          * not sure if the assumption holds, as it depends on *caller's* 
 913          * behavior, not the behavior of this function. 
 914          * IMHO it is wrong to make assumption on the caller's behavior, 
 915          * so the above #if is #if 1, not #ifdef DIAGNOSTIC. 
 917         *curpps 
= *curpps 
+ 1; 
 922 #endif /* NETWORKING */ 
 925 time_zone_slock_init(void) 
 927         /* allocate lock group attribute and group */ 
 928         tz_slock_grp_attr 
= lck_grp_attr_alloc_init(); 
 930         tz_slock_grp 
=  lck_grp_alloc_init("tzlock", tz_slock_grp_attr
); 
 932         /* Allocate lock attribute */ 
 933         tz_slock_attr 
= lck_attr_alloc_init(); 
 935         /* Allocate the spin lock */ 
 936         tz_slock 
= lck_spin_alloc_init(tz_slock_grp
, tz_slock_attr
); 
 940 __mach_bridge_remote_time(__unused 
struct proc 
*p
, struct __mach_bridge_remote_time_args 
*mbrt_args
, uint64_t *retval
) 
 942         *retval 
= mach_bridge_remote_time(mbrt_args
->local_timestamp
);