/ duct-tape / xnu / osfmk / kern / ipc_clock.c
ipc_clock.c
  1  /*
  2   * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
  3   *
  4   * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  5   *
  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.
 14   *
 15   * Please obtain a copy of the License at
 16   * http://www.opensource.apple.com/apsl/ and read it before using this file.
 17   *
 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.
 25   *
 26   * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 27   */
 28  /*
 29   * @OSF_COPYRIGHT@
 30   */
 31  /*
 32   *	File:		kern/ipc_clock.c
 33   *	Purpose:	Routines to support ipc semantics of new kernel
 34   *			alarm clock facility.
 35   */
 36  
 37  #include <mach/message.h>
 38  #include <kern/host.h>
 39  #include <kern/processor.h>
 40  #include <kern/task.h>
 41  #include <kern/thread.h>
 42  #include <kern/ipc_host.h>
 43  #include <kern/ipc_kobject.h>
 44  #include <kern/clock.h>
 45  #include <kern/misc_protos.h>
 46  #include <ipc/ipc_port.h>
 47  #include <ipc/ipc_space.h>
 48  
 49  /*
 50   *	Routine:	ipc_clock_init
 51   *	Purpose:
 52   *		Initialize ipc control of a clock.
 53   */
 54  void
 55  ipc_clock_init(
 56  	clock_t         clock)
 57  {
 58  	ipc_port_t      port;
 59  
 60  	port = ipc_port_alloc_kernel();
 61  	if (port == IP_NULL) {
 62  		panic("ipc_clock_init");
 63  	}
 64  	clock->cl_service = port;
 65  
 66  	port = ipc_port_alloc_kernel();
 67  	if (port == IP_NULL) {
 68  		panic("ipc_clock_init");
 69  	}
 70  	clock->cl_control = port;
 71  }
 72  
 73  /*
 74   *	Routine:	ipc_clock_enable
 75   *	Purpose:
 76   *		Enable ipc access to a clock.
 77   */
 78  void
 79  ipc_clock_enable(
 80  	clock_t         clock)
 81  {
 82  	ipc_kobject_set(clock->cl_service,
 83  	    (ipc_kobject_t) clock, IKOT_CLOCK);
 84  	ipc_kobject_set(clock->cl_control,
 85  	    (ipc_kobject_t) clock, IKOT_CLOCK_CTRL);
 86  }
 87  
 88  /*
 89   *	Routine:	convert_port_to_clock
 90   *	Purpose:
 91   *		Convert from a port to a clock.
 92   *		Doesn't consume the port ref; produces a clock ref,
 93   *		which may be null.
 94   *	Conditions:
 95   *		Nothing locked.
 96   */
 97  clock_t
 98  convert_port_to_clock(
 99  	ipc_port_t      port)
100  {
101  	clock_t         clock = CLOCK_NULL;
102  
103  	if (IP_VALID(port)) {
104  		ip_lock(port);
105  		if (ip_active(port) &&
106  		    ((ip_kotype(port) == IKOT_CLOCK) ||
107  		    (ip_kotype(port) == IKOT_CLOCK_CTRL))) {
108  			clock = (clock_t)ip_get_kobject(port);
109  		}
110  		ip_unlock(port);
111  	}
112  	return clock;
113  }
114  
115  /*
116   *	Routine:	convert_port_to_clock_ctrl
117   *	Purpose:
118   *		Convert from a port to a clock.
119   *		Doesn't consume the port ref; produces a clock ref,
120   *		which may be null.
121   *	Conditions:
122   *		Nothing locked.
123   */
124  clock_t
125  convert_port_to_clock_ctrl(
126  	ipc_port_t      port)
127  {
128  	clock_t         clock = CLOCK_NULL;
129  
130  	if (IP_VALID(port)) {
131  		ip_lock(port);
132  		if (ip_active(port) &&
133  		    (ip_kotype(port) == IKOT_CLOCK_CTRL)) {
134  			clock = (clock_t) ip_get_kobject(port);
135  		}
136  		ip_unlock(port);
137  	}
138  	return clock;
139  }
140  
141  /*
142   *	Routine:	convert_clock_to_port
143   *	Purpose:
144   *		Convert from a clock to a port.
145   *		Produces a naked send right which may be invalid.
146   *	Conditions:
147   *		Nothing locked.
148   */
149  ipc_port_t
150  convert_clock_to_port(
151  	clock_t         clock)
152  {
153  	ipc_port_t      port;
154  
155  	port = ipc_port_make_send(clock->cl_service);
156  	return port;
157  }
158  
159  /*
160   *	Routine:	convert_clock_ctrl_to_port
161   *	Purpose:
162   *		Convert from a clock to a port.
163   *		Produces a naked send right which may be invalid.
164   *	Conditions:
165   *		Nothing locked.
166   */
167  ipc_port_t
168  convert_clock_ctrl_to_port(
169  	clock_t         clock)
170  {
171  	ipc_port_t      port;
172  
173  	port = ipc_port_make_send(clock->cl_control);
174  	return port;
175  }
176  
177  /*
178   *	Routine:	port_name_to_clock
179   *	Purpose:
180   *		Convert from a clock name to a clock pointer.
181   */
182  clock_t
183  port_name_to_clock(
184  	mach_port_name_t clock_name)
185  {
186  	clock_t         clock = CLOCK_NULL;
187  	ipc_space_t     space;
188  	ipc_port_t      port;
189  
190  	if (clock_name == 0) {
191  		return clock;
192  	}
193  	space = current_space();
194  	if (ipc_port_translate_send(space, clock_name, &port) != KERN_SUCCESS) {
195  		return clock;
196  	}
197  	if (ip_kotype(port) == IKOT_CLOCK) {
198  		clock = (clock_t) ip_get_kobject(port);
199  	}
200  	ip_unlock(port);
201  	return clock;
202  }