xref: /xnu-8020.101.4/osfmk/kern/ipc_clock.c (revision e7776783b89a353188416a9a346c6cdb4928faad)
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 IPC_KOBJECT_DEFINE(IKOT_CLOCK,
50     .iko_op_stable    = true,
51     .iko_op_permanent = true);
52 IPC_KOBJECT_DEFINE(IKOT_CLOCK_CTRL,
53     .iko_op_stable    = true,
54     .iko_op_permanent = true);
55 
56 /*
57  *	Routine:	ipc_clock_init
58  *	Purpose:
59  *		Initialize ipc control of a clock.
60  */
61 void
ipc_clock_init(clock_t clock)62 ipc_clock_init(clock_t clock)
63 {
64 	clock->cl_service = ipc_kobject_alloc_port(clock, IKOT_CLOCK,
65 	    IPC_KOBJECT_ALLOC_NONE);
66 	clock->cl_control = ipc_kobject_alloc_port(clock, IKOT_CLOCK_CTRL,
67 	    IPC_KOBJECT_ALLOC_NONE);
68 }
69 
70 /*
71  *	Routine:	convert_port_to_clock
72  *	Purpose:
73  *		Convert from a port to a clock.
74  *		Doesn't consume the port ref
75  *		which may be null.
76  *	Conditions:
77  *		Nothing locked.
78  */
79 clock_t
convert_port_to_clock(ipc_port_t port)80 convert_port_to_clock(ipc_port_t port)
81 {
82 	clock_t clock = CLOCK_NULL;
83 	ipc_kobject_type_t type;
84 
85 	if (IP_VALID(port)) {
86 		type = ip_kotype(port);
87 		if (type == IKOT_CLOCK || type == IKOT_CLOCK_CTRL) {
88 			clock = (clock_t)ipc_kobject_get_stable(port, type);
89 		}
90 	}
91 
92 	return clock;
93 }
94 
95 /*
96  *	Routine:	convert_port_to_clock_ctrl
97  *	Purpose:
98  *		Convert from a port to a clock.
99  *		Doesn't consume the port ref
100  *		which may be null.
101  *	Conditions:
102  *		Nothing locked.
103  */
104 clock_t
convert_port_to_clock_ctrl(ipc_port_t port)105 convert_port_to_clock_ctrl(ipc_port_t port)
106 {
107 	clock_t clock = CLOCK_NULL;
108 
109 	if (IP_VALID(port)) {
110 		clock = (clock_t)ipc_kobject_get_stable(port, IKOT_CLOCK_CTRL);
111 	}
112 	return clock;
113 }
114 
115 /*
116  *	Routine:	convert_clock_to_port
117  *	Purpose:
118  *		Convert from a clock to a port.
119  *		Produces a naked send right which may be invalid.
120  *	Conditions:
121  *		Nothing locked.
122  */
123 ipc_port_t
convert_clock_to_port(clock_t clock)124 convert_clock_to_port(clock_t clock)
125 {
126 	return ipc_port_make_send(clock->cl_service);
127 }
128 
129 /*
130  *	Routine:	convert_clock_ctrl_to_port
131  *	Purpose:
132  *		Convert from a clock to a port.
133  *		Produces a naked send right which may be invalid.
134  *	Conditions:
135  *		Nothing locked.
136  */
137 ipc_port_t
convert_clock_ctrl_to_port(clock_t clock)138 convert_clock_ctrl_to_port(clock_t clock)
139 {
140 	return ipc_port_make_send(clock->cl_control);
141 }
142 
143 /*
144  *	Routine:	port_name_to_clock
145  *	Purpose:
146  *		Convert from a clock name to a clock pointer.
147  */
148 clock_t
port_name_to_clock(mach_port_name_t clock_name)149 port_name_to_clock(mach_port_name_t clock_name)
150 {
151 	clock_t         clock = CLOCK_NULL;
152 	ipc_space_t     space;
153 	ipc_port_t      port;
154 
155 	if (clock_name == 0) {
156 		return clock;
157 	}
158 	space = current_space();
159 	if (ipc_port_translate_send(space, clock_name, &port) != KERN_SUCCESS) {
160 		return clock;
161 	}
162 	clock = (clock_t)ipc_kobject_get_stable(port, IKOT_CLOCK);
163 	ip_mq_unlock(port);
164 	return clock;
165 }
166