X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/91447636331957f3d9b5ca5b508f07c526b0074d..d9a64523371fa019c4575bb400cbbc3a50ac9903:/osfmk/kern/timer.c diff --git a/osfmk/kern/timer.c b/osfmk/kern/timer.c index 4dc36f6b5..8ccba9e2c 100644 --- a/osfmk/kern/timer.c +++ b/osfmk/kern/timer.c @@ -1,57 +1,58 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2018 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ */ -/* +/* * Mach Operating System * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University * All Rights Reserved. - * + * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. - * + * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * + * * Carnegie Mellon requests users of this software to return to - * + * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 - * + * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ -/* - */ - -#include -#include #include #include @@ -61,118 +62,87 @@ #include #include -/* - * timer_init initializes a timer. - */ +#if CONFIG_EMBEDDED +int precise_user_kernel_time = 0; +#else +int precise_user_kernel_time = 1; +#endif + void -timer_init( - timer_t timer) +timer_init(timer_t timer) { - timer->low_bits = 0; - timer->high_bits = 0; - timer->high_bits_check = 0; -#if !STAT_TIME - timer->tstamp = 0; -#endif /* STAT_TIME */ + memset(timer, 0, sizeof(*timer)); } -/* - * Calculate the difference between a timer - * and saved value, and update the saved value. - */ uint64_t -timer_delta( - timer_t timer, - uint64_t *save) +timer_delta(timer_t timer, uint64_t *prev_in_cur_out) { - uint64_t new, old = *save; - - *save = new = timer_grab(timer); - + uint64_t old = *prev_in_cur_out; + uint64_t new = *prev_in_cur_out = timer_grab(timer); return (new - old); } -#if !STAT_TIME - -/* - * Update the current timer (if any) - * and start the new timer, which - * could be either the same or NULL. - * - * Called with interrupts disabled. - */ -void -timer_switch( - uint32_t tstamp, - timer_t new_timer) +static void +timer_advance(timer_t timer, uint64_t delta) { - processor_t processor = current_processor(); - timer_t timer; - uint32_t old_low, low; - - /* - * Update current timer. - */ - timer = PROCESSOR_DATA(processor, current_timer); - if (timer != NULL) { - old_low = timer->low_bits; - low = old_low + tstamp - timer->tstamp; - if (low < old_low) - timer_update(timer, timer->high_bits + 1, low); - else - timer->low_bits = low; +#if defined(__LP64__) + timer->all_bits += delta; +#else /* defined(__LP64__) */ + extern void timer_advance_internal_32(timer_t timer, uint32_t high, + uint32_t low); + uint64_t low = delta + timer->low_bits; + if (low >> 32) { + timer_advance_internal_32(timer, + (uint32_t)(timer->high_bits + (low >> 32)), (uint32_t)low); + } else { + timer->low_bits = (uint32_t)low; } +#endif /* defined(__LP64__) */ +} - /* - * Start new timer. - */ - PROCESSOR_DATA(processor, current_timer) = new_timer; - if (new_timer != NULL) - new_timer->tstamp = tstamp; +void +timer_start(timer_t timer, uint64_t tstamp) +{ + timer->tstamp = tstamp; } -#if MACHINE_TIMER_ROUTINES +void +timer_stop(timer_t timer, uint64_t tstamp) +{ + timer_advance(timer, tstamp - timer->tstamp); +} -/* - * Machine-dependent code implements the timer event routine. - */ +void +timer_update(timer_t timer, uint64_t tstamp) +{ + timer_advance(timer, tstamp - timer->tstamp); + timer->tstamp = tstamp; +} -#else /* MACHINE_TIMER_ROUTINES */ +void +timer_switch(timer_t timer, uint64_t tstamp, timer_t new_timer) +{ + timer_advance(timer, tstamp - timer->tstamp); + new_timer->tstamp = tstamp; +} /* - * Update the current timer and start - * the new timer. Requires a current - * and new timer. + * Update the current processor's thread timer with `tstamp` and switch the + * processor's thread timer to `new_timer`. * - * Called with interrupts disabled. + * Called with interrupts disabled. */ void -timer_event( - uint32_t tstamp, - timer_t new_timer) +processor_timer_switch_thread(uint64_t tstamp, timer_t new_timer) { - processor_t processor = current_processor(); - timer_t timer; - uint32_t old_low, low; + processor_t processor = current_processor(); + timer_t timer; - /* - * Update current timer. - */ - timer = PROCESSOR_DATA(processor, current_timer); - old_low = timer->low_bits; - low = old_low + tstamp - timer->tstamp; - if (low < old_low) - timer_update(timer, timer->high_bits + 1, low); - else - timer->low_bits = low; + /* Update current timer. */ + timer = PROCESSOR_DATA(processor, thread_timer); + timer_advance(timer, tstamp - timer->tstamp); - /* - * Start new timer. - */ - PROCESSOR_DATA(processor, current_timer) = new_timer; + /* Start new timer. */ + PROCESSOR_DATA(processor, thread_timer) = new_timer; new_timer->tstamp = tstamp; } - -#endif /* MACHINE_TIMER_ROUTINES */ - -#endif /* STAT_TIME */