1/* 2 * Copyright (c) 2000-2009 Apple 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 * Mach Operating System 33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56/* 57 */ 58 59/* 60 * processor.h: Processor and processor-related definitions. 61 */ 62 63#ifndef _KERN_PROCESSOR_H_ 64#define _KERN_PROCESSOR_H_ 65 66#include <mach/boolean.h> 67#include <mach/kern_return.h> 68#include <kern/kern_types.h> 69 70#include <sys/cdefs.h> 71 72#ifdef MACH_KERNEL_PRIVATE 73 74#include <mach/mach_types.h> 75#include <kern/ast.h> 76#include <kern/cpu_number.h> 77#include <kern/simple_lock.h> 78#include <kern/locks.h> 79#include <kern/queue.h> 80#include <kern/sched.h> 81#include <mach/sfi_class.h> 82#include <kern/processor_data.h> 83 84#include <machine/ast_types.h> 85 86struct processor_set { 87 queue_head_t active_queue; /* active processors */ 88 queue_head_t idle_queue; /* idle processors */ 89 queue_head_t idle_secondary_queue; /* idle secondary processors */ 90 91 int online_processor_count; 92 93 int cpu_set_low, cpu_set_hi; 94 int cpu_set_count; 95 96 decl_simple_lock_data(,sched_lock) /* lock for above */ 97 98#if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_MULTIQ) 99 struct run_queue pset_runq; /* runq for this processor set */ 100#endif 101 102#if defined(CONFIG_SCHED_TRADITIONAL) 103 int pset_runq_bound_count; 104 /* # of threads in runq bound to any processor in pset */ 105#endif 106 107 /* CPUs that have been sent an unacknowledged remote AST for scheduling purposes */ 108 uint32_t pending_AST_cpu_mask; 109 110 struct ipc_port * pset_self; /* port for operations */ 111 struct ipc_port * pset_name_self; /* port for information */ 112 113 processor_set_t pset_list; /* chain of associated psets */ 114 pset_node_t node; 115}; 116 117extern struct processor_set pset0; 118 119struct pset_node { 120 processor_set_t psets; /* list of associated psets */ 121 122 pset_node_t nodes; /* list of associated subnodes */ 123 pset_node_t node_list; /* chain of associated nodes */ 124 125 pset_node_t parent; 126}; 127 128extern struct pset_node pset_node0; 129 130extern queue_head_t tasks, terminated_tasks, threads; /* Terminated tasks are ONLY for stackshot */ 131extern int tasks_count, terminated_tasks_count, threads_count; 132decl_lck_mtx_data(extern,tasks_threads_lock) 133 134struct processor { 135 queue_chain_t processor_queue;/* idle/active queue link, 136 * MUST remain the first element */ 137 int state; /* See below */ 138 boolean_t is_SMT; 139 struct thread 140 *active_thread, /* thread running on processor */ 141 *next_thread, /* next thread when dispatched */ 142 *idle_thread; /* this processor's idle thread. */ 143 144 processor_set_t processor_set; /* assigned set */ 145 146 int current_pri; /* priority of current thread */ 147 sched_mode_t current_thmode; /* sched mode of current thread */ 148 sfi_class_id_t current_sfi_class; /* SFI class of current thread */ 149 int cpu_id; /* platform numeric id */ 150 151 timer_call_data_t quantum_timer; /* timer for quantum expiration */ 152 uint64_t quantum_end; /* time when current quantum ends */ 153 uint64_t last_dispatch; /* time of last dispatch */ 154 155 uint64_t deadline; /* current deadline */ 156 int timeslice; /* quanta before timeslice ends */ 157 158#if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_MULTIQ) 159 struct run_queue runq; /* runq for this processor */ 160#endif 161 162#if defined(CONFIG_SCHED_TRADITIONAL) 163 int runq_bound_count; /* # of threads bound to this processor */ 164#endif 165#if defined(CONFIG_SCHED_GRRR) 166 struct grrr_run_queue grrr_runq; /* Group Ratio Round-Robin runq */ 167#endif 168 169 processor_t processor_primary; /* pointer to primary processor for 170 * secondary SMT processors, or a pointer 171 * to ourselves for primaries or non-SMT */ 172 processor_t processor_secondary; 173 struct ipc_port * processor_self; /* port for operations */ 174 175 processor_t processor_list; /* all existing processors */ 176 processor_data_t processor_data; /* per-processor data */ 177}; 178 179extern processor_t processor_list; 180extern unsigned int processor_count; 181decl_simple_lock_data(extern,processor_list_lock) 182 183extern uint32_t processor_avail_count; 184 185extern processor_t master_processor; 186 187extern boolean_t sched_stats_active; 188 189/* 190 * Processor state is accessed by locking the scheduling lock 191 * for the assigned processor set. 192 * 193 * -------------------- SHUTDOWN 194 * / ^ ^ 195 * _/ | \ 196 * OFF_LINE ---> START ---> RUNNING ---> IDLE ---> DISPATCHING 197 * \_________________^ ^ ^______/ / 198 * \__________________/ 199 * 200 * Most of these state transitions are externally driven as a 201 * a directive (for instance telling an IDLE processor to start 202 * coming out of the idle state to run a thread). However these 203 * are typically paired with a handshake by the processor itself 204 * to indicate that it has completed a transition of indeterminate 205 * length (for example, the DISPATCHING->RUNNING or START->RUNNING 206 * transitions must occur on the processor itself). 207 * 208 * The boot processor has some special cases, and skips the START state, 209 * since it has already bootstrapped and is ready to context switch threads. 210 * 211 * When a processor is in DISPATCHING or RUNNING state, the current_pri, 212 * current_thmode, and deadline fields should be set, so that other 213 * processors can evaluate if it is an appropriate candidate for preemption. 214*/ 215#define PROCESSOR_OFF_LINE 0 /* Not available */ 216#define PROCESSOR_SHUTDOWN 1 /* Going off-line */ 217#define PROCESSOR_START 2 /* Being started */ 218/* 3 Formerly Inactive (unavailable) */ 219#define PROCESSOR_IDLE 4 /* Idle (available) */ 220#define PROCESSOR_DISPATCHING 5 /* Dispatching (idle -> active) */ 221#define PROCESSOR_RUNNING 6 /* Normal execution */ 222 223extern processor_t current_processor(void); 224 225/* Lock macros */ 226 227#define pset_lock(p) simple_lock(&(p)->sched_lock) 228#define pset_unlock(p) simple_unlock(&(p)->sched_lock) 229#define pset_lock_init(p) simple_lock_init(&(p)->sched_lock, 0) 230 231extern void processor_bootstrap(void); 232 233extern void processor_init( 234 processor_t processor, 235 int cpu_id, 236 processor_set_t processor_set); 237 238extern void processor_set_primary( 239 processor_t processor, 240 processor_t primary); 241 242extern kern_return_t processor_shutdown( 243 processor_t processor); 244 245extern void processor_queue_shutdown( 246 processor_t processor); 247 248extern processor_set_t processor_pset( 249 processor_t processor); 250 251extern pset_node_t pset_node_root(void); 252 253extern processor_set_t pset_create( 254 pset_node_t node); 255 256extern void pset_init( 257 processor_set_t pset, 258 pset_node_t node); 259 260extern kern_return_t processor_info_count( 261 processor_flavor_t flavor, 262 mach_msg_type_number_t *count); 263 264#define pset_deallocate(x) 265#define pset_reference(x) 266 267extern void machine_run_count( 268 uint32_t count); 269 270extern processor_t machine_choose_processor( 271 processor_set_t pset, 272 processor_t processor); 273 274#define next_pset(p) (((p)->pset_list != PROCESSOR_SET_NULL)? (p)->pset_list: (p)->node->psets) 275 276#else /* MACH_KERNEL_PRIVATE */ 277 278__BEGIN_DECLS 279 280extern void pset_deallocate( 281 processor_set_t pset); 282 283extern void pset_reference( 284 processor_set_t pset); 285 286__END_DECLS 287 288#endif /* MACH_KERNEL_PRIVATE */ 289 290#ifdef KERNEL_PRIVATE 291__BEGIN_DECLS 292extern processor_t cpu_to_processor(int cpu); 293__END_DECLS 294 295#endif /* KERNEL_PRIVATE */ 296 297#endif /* _KERN_PROCESSOR_H_ */ 298