X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/6601e61aa18bf4f09af135ff61fc7f4771d23b06..94ff46dc2849db4d43eaaf144872decc522aafb4:/bsd/net/devtimer.c diff --git a/bsd/net/devtimer.c b/bsd/net/devtimer.c index 4344f3a9f..4e4edad68 100644 --- a/bsd/net/devtimer.c +++ b/bsd/net/devtimer.c @@ -1,27 +1,33 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004,2007-2008 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@ */ /* - * devtimer.c + * devtimer.c * - timer source based on */ @@ -36,241 +42,227 @@ #include #include #include -#include +#include #ifdef DEVTIMER_DEBUG -#define _devtimer_printf printf -#else DEVTIMER_DEBUG +#define _devtimer_printf printf +#else /* !DEVTIMER_DEBUG */ static __inline__ void _devtimer_printf(__unused const char * fmt, ...) { } -#endif DEVTIMER_DEBUG +#endif /* !DEVTIMER_DEBUG */ struct devtimer_s { - void * dt_callout; - devtimer_timeout_func dt_timeout_func; - devtimer_process_func dt_process_func; - void * dt_arg0; - void * dt_arg1; - void * dt_arg2; - int dt_generation; - UInt32 dt_retain_count; + void * dt_callout; + devtimer_timeout_func dt_timeout_func; + devtimer_process_func dt_process_func; + void * dt_arg0; + void * dt_arg1; + void * dt_arg2; + int dt_generation; + struct os_refcnt dt_retain_count; }; -#define M_DEVTIMER M_DEVBUF +#define M_DEVTIMER M_DEVBUF static __inline__ void timeval_add(struct timeval tv1, struct timeval tv2, - struct timeval * result) + struct timeval * result) { - result->tv_sec = tv1.tv_sec + tv2.tv_sec; - result->tv_usec = tv1.tv_usec + tv2.tv_usec; - if (result->tv_usec > DEVTIMER_USECS_PER_SEC) { - result->tv_usec -= DEVTIMER_USECS_PER_SEC; - result->tv_sec++; - } - return; + result->tv_sec = tv1.tv_sec + tv2.tv_sec; + result->tv_usec = tv1.tv_usec + tv2.tv_usec; + if (result->tv_usec > DEVTIMER_USECS_PER_SEC) { + result->tv_usec -= DEVTIMER_USECS_PER_SEC; + result->tv_sec++; + } + return; } static __inline__ uint64_t timeval_to_absolutetime(struct timeval tv) { - uint64_t secs; - uint64_t usecs; + uint64_t secs; + uint64_t usecs; - clock_interval_to_absolutetime_interval(tv.tv_sec, NSEC_PER_SEC, - &secs); - clock_interval_to_absolutetime_interval(tv.tv_usec, NSEC_PER_USEC, - &usecs); - return (secs + usecs); + clock_interval_to_absolutetime_interval(tv.tv_sec, NSEC_PER_SEC, + &secs); + clock_interval_to_absolutetime_interval(tv.tv_usec, NSEC_PER_USEC, + &usecs); + return secs + usecs; } __private_extern__ int devtimer_valid(devtimer_ref timer) { - return (timer->dt_callout != NULL); + return timer->dt_callout != NULL; } __private_extern__ void devtimer_retain(devtimer_ref timer) { - OSIncrementAtomic(&timer->dt_retain_count); - return; + os_ref_retain(&timer->dt_retain_count); } __private_extern__ void devtimer_invalidate(devtimer_ref timer) { - devtimer_cancel(timer); - timer->dt_arg0 = NULL; - if (timer->dt_callout != NULL) { - thread_call_free(timer->dt_callout); - timer->dt_callout = NULL; - } - return; + devtimer_cancel(timer); + timer->dt_arg0 = NULL; + if (timer->dt_callout != NULL) { + thread_call_free(timer->dt_callout); + timer->dt_callout = NULL; + } + return; } __private_extern__ void devtimer_release(devtimer_ref timer) { - UInt32 old_retain_count; - - old_retain_count = OSDecrementAtomic(&timer->dt_retain_count); - switch (old_retain_count) { - case 0: - panic("devtimer_release: retain count is 0\n"); - break; - case 1: - devtimer_invalidate(timer); - FREE(timer, M_DEVTIMER); - _devtimer_printf("devtimer: timer released\n"); - break; - default: - break; - } - return; + if (os_ref_release(&timer->dt_retain_count) == 0) { + devtimer_invalidate(timer); + FREE(timer, M_DEVTIMER); + _devtimer_printf("devtimer: timer released\n"); + } } static void devtimer_process(void * param0, void * param1) { - int generation = (int)param1; - devtimer_process_func process_func; - devtimer_timeout_func timeout_func; - devtimer_ref timer = (devtimer_ref)param0; + int generation = *(int*)param1; + devtimer_process_func process_func; + devtimer_timeout_func timeout_func; + devtimer_ref timer = (devtimer_ref)param0; - process_func = timer->dt_process_func; - if (process_func != NULL) { - (*process_func)(timer, devtimer_process_func_event_lock); - } - timeout_func = timer->dt_timeout_func; - if (timeout_func != NULL) { - timer->dt_timeout_func = NULL; - if (timer->dt_generation == generation) { - (*timeout_func)(timer->dt_arg0, timer->dt_arg1, timer->dt_arg2); + process_func = timer->dt_process_func; + if (process_func != NULL) { + (*process_func)(timer, devtimer_process_func_event_lock); + } + timeout_func = timer->dt_timeout_func; + if (timeout_func != NULL) { + timer->dt_timeout_func = NULL; + if (timer->dt_generation == generation) { + (*timeout_func)(timer->dt_arg0, timer->dt_arg1, timer->dt_arg2); + } + } + devtimer_release(timer); + if (process_func != NULL) { + (*process_func)(timer, devtimer_process_func_event_unlock); } - } - devtimer_release(timer); - if (process_func != NULL) { - (*process_func)(timer, devtimer_process_func_event_unlock); - } - return; + return; } __private_extern__ void * devtimer_arg0(devtimer_ref timer) { - return (timer->dt_arg0); + return timer->dt_arg0; } __private_extern__ devtimer_ref devtimer_create(devtimer_process_func process_func, void * arg0) { - devtimer_ref timer; + devtimer_ref timer; - timer = _MALLOC(sizeof(*timer), M_DEVTIMER, M_WAITOK); - if (timer == NULL) { - return (timer); - } - bzero(timer, sizeof(*timer)); - devtimer_retain(timer); - timer->dt_callout = thread_call_allocate(devtimer_process, timer); - if (timer->dt_callout == NULL) { - _devtimer_printf("devtimer: thread_call_allocate failed\n"); - devtimer_release(timer); - timer = NULL; - } - timer->dt_process_func = process_func; - timer->dt_arg0 = arg0; - return (timer); + timer = _MALLOC(sizeof(*timer), M_DEVTIMER, M_WAITOK | M_ZERO); + if (timer == NULL) { + return timer; + } + os_ref_init(&timer->dt_retain_count, NULL); + timer->dt_callout = thread_call_allocate(devtimer_process, timer); + if (timer->dt_callout == NULL) { + _devtimer_printf("devtimer: thread_call_allocate failed\n"); + devtimer_release(timer); + timer = NULL; + } + timer->dt_process_func = process_func; + timer->dt_arg0 = arg0; + return timer; } __private_extern__ void -devtimer_set_absolute(devtimer_ref timer, - struct timeval abs_time, - devtimer_timeout_func timeout_func, - void * arg1, void * arg2) +devtimer_set_absolute(devtimer_ref timer, + struct timeval abs_time, + devtimer_timeout_func timeout_func, + void * arg1, void * arg2) { - if (timer->dt_callout == NULL) { - printf("devtimer_set_absolute: uninitialized/freed timer\n"); - return; - } - devtimer_cancel(timer); - if (timeout_func == NULL) { + if (timer->dt_callout == NULL) { + printf("devtimer_set_absolute: uninitialized/freed timer\n"); + return; + } + devtimer_cancel(timer); + if (timeout_func == NULL) { + return; + } + timer->dt_timeout_func = timeout_func; + timer->dt_arg1 = arg1; + timer->dt_arg2 = arg2; + _devtimer_printf("devtimer: wakeup time is (%d.%d)\n", + abs_time.tv_sec, abs_time.tv_usec); + timer->dt_generation++; + devtimer_retain(timer); + thread_call_enter1_delayed(timer->dt_callout, + &timer->dt_generation, + timeval_to_absolutetime(abs_time)); return; - } - timer->dt_timeout_func = timeout_func; - timer->dt_arg1 = arg1; - timer->dt_arg2 = arg2; - _devtimer_printf("devtimer: wakeup time is (%d.%d)\n", - abs_time.tv_sec, abs_time.tv_usec); - timer->dt_generation++; - devtimer_retain(timer); - thread_call_enter1_delayed(timer->dt_callout, - (thread_call_param_t)timer->dt_generation, - timeval_to_absolutetime(abs_time)); - return; } __private_extern__ void -devtimer_set_relative(devtimer_ref timer, - struct timeval rel_time, - devtimer_timeout_func timeout_func, - void * arg1, void * arg2) +devtimer_set_relative(devtimer_ref timer, + struct timeval rel_time, + devtimer_timeout_func timeout_func, + void * arg1, void * arg2) { - struct timeval abs_time; - struct timeval current_time; + struct timeval abs_time; + struct timeval current_time; - current_time = devtimer_current_time(); - timeval_add(current_time, rel_time, &abs_time); - devtimer_set_absolute(timer, abs_time, timeout_func, arg1, arg2); - return; + current_time = devtimer_current_time(); + timeval_add(current_time, rel_time, &abs_time); + devtimer_set_absolute(timer, abs_time, timeout_func, arg1, arg2); + return; } __private_extern__ void devtimer_cancel(devtimer_ref timer) { - if (timer->dt_timeout_func != NULL) { - timer->dt_timeout_func = NULL; - if (timer->dt_callout != NULL) { - _devtimer_printf("devtimer: cancelling timer source\n"); - if (thread_call_cancel(timer->dt_callout)) { - devtimer_release(timer); - } - else { - _devtimer_printf("devtimer: delayed release\n"); - } + if (timer->dt_timeout_func != NULL) { + timer->dt_timeout_func = NULL; + if (timer->dt_callout != NULL) { + _devtimer_printf("devtimer: cancelling timer source\n"); + if (thread_call_cancel(timer->dt_callout)) { + devtimer_release(timer); + } else { + _devtimer_printf("devtimer: delayed release\n"); + } + } } - } - return; + return; } __private_extern__ int devtimer_enabled(devtimer_ref timer) { - return (timer->dt_timeout_func != NULL); + return timer->dt_timeout_func != NULL; } __private_extern__ int32_t devtimer_current_secs(void) { - struct timeval tv; + struct timeval tv; - tv = devtimer_current_time(); - return (tv.tv_sec); + tv = devtimer_current_time(); + return tv.tv_sec; } __private_extern__ struct timeval devtimer_current_time(void) { - struct timeval tv; - uint32_t sec; - uint32_t usec; + struct timeval tv; + clock_sec_t sec; + clock_usec_t usec; - clock_get_system_microtime(&sec, &usec); - tv.tv_sec = sec; - tv.tv_usec = usec; - return (tv); + clock_get_system_microtime(&sec, &usec); + tv.tv_sec = sec; + tv.tv_usec = usec; + return tv; }