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 }