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/lock.h> 78#include <kern/queue.h> 79#include <kern/sched.h> 80#include <kern/processor_data.h> 81 82#include <machine/ast_types.h> 83 84struct processor_set { 85 queue_head_t active_queue; /* active processors */ 86 queue_head_t idle_queue; /* idle processors */ 87 88 processor_t low_pri, low_count; 89 90 int online_processor_count; 91 92 int cpu_set_low, cpu_set_hi; 93 int cpu_set_count; 94 95 decl_simple_lock_data(,sched_lock) /* lock for above */ 96 97#if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_FIXEDPRIORITY) 98 struct run_queue pset_runq; /* runq for this processor set */ 99 int pset_runq_bound_count; 100 /* # of threads in runq bound to any processor in pset */ 101#endif 102 103 /* CPUs that have been sent an unacknowledged remote AST for scheduling purposes */ 104 uint32_t pending_AST_cpu_mask; 105 106 struct ipc_port * pset_self; /* port for operations */ 107 struct ipc_port * pset_name_self; /* port for information */ 108 109 processor_set_t pset_list; /* chain of associated psets */ 110 pset_node_t node; 111}; 112 113extern struct processor_set pset0; 114 115struct pset_node { 116 processor_set_t psets; /* list of associated psets */ 117 118 pset_node_t nodes; /* list of associated subnodes */ 119 pset_node_t node_list; /* chain of associated nodes */ 120 121 pset_node_t parent; 122}; 123 124extern struct pset_node pset_node0; 125 126extern queue_head_t tasks, terminated_tasks, threads; /* Terminated tasks are ONLY for stackshot */ 127extern int tasks_count, terminated_tasks_count, threads_count; 128decl_lck_mtx_data(extern,tasks_threads_lock) 129 130struct processor_meta { 131 queue_head_t idle_queue; 132 processor_t primary; 133}; 134 135typedef struct processor_meta *processor_meta_t; 136#define PROCESSOR_META_NULL ((processor_meta_t) 0) 137 138struct processor { 139 queue_chain_t processor_queue;/* idle/active queue link, 140 * MUST remain the first element */ 141 int state; /* See below */ 142 struct thread 143 *active_thread, /* thread running on processor */ 144 *next_thread, /* next thread when dispatched */ 145 *idle_thread; /* this processor's idle thread. */ 146 147 processor_set_t processor_set; /* assigned set */ 148 149 int current_pri; /* priority of current thread */ 150 sched_mode_t current_thmode; /* sched mode of current thread */ 151 int cpu_id; /* platform numeric id */ 152 153 timer_call_data_t quantum_timer; /* timer for quantum expiration */ 154 uint64_t quantum_end; /* time when current quantum ends */ 155 uint64_t last_dispatch; /* time of last dispatch */ 156 157 uint64_t deadline; /* current deadline */ 158 int timeslice; /* quanta before timeslice ends */ 159 160#if defined(CONFIG_SCHED_TRADITIONAL) || defined(CONFIG_SCHED_FIXEDPRIORITY) 161 struct run_queue runq; /* runq for this processor */ 162 int runq_bound_count; /* # of threads bound to this processor */ 163#endif 164#if defined(CONFIG_SCHED_GRRR) 165 struct grrr_run_queue grrr_runq; /* Group Ratio Round-Robin runq */ 166#endif 167 processor_meta_t processor_meta; 168 169 struct ipc_port * processor_self; /* port for operations */ 170 171 processor_t processor_list; /* all existing processors */ 172 processor_data_t processor_data; /* per-processor data */ 173}; 174 175extern processor_t processor_list; 176extern unsigned int processor_count; 177decl_simple_lock_data(extern,processor_list_lock) 178 179extern uint32_t processor_avail_count; 180 181extern processor_t master_processor; 182 183extern boolean_t sched_stats_active; 184 185/* 186 * Processor state is accessed by locking the scheduling lock 187 * for the assigned processor set. 188 */ 189#define PROCESSOR_OFF_LINE 0 /* Not available */ 190#define PROCESSOR_SHUTDOWN 1 /* Going off-line */ 191#define PROCESSOR_START 2 /* Being started */ 192#define PROCESSOR_INACTIVE 3 /* Inactive (unavailable) */ 193#define PROCESSOR_IDLE 4 /* Idle (available) */ 194#define PROCESSOR_DISPATCHING 5 /* Dispatching (idle -> active) */ 195#define PROCESSOR_RUNNING 6 /* Normal execution */ 196 197extern processor_t current_processor(void); 198 199extern processor_t cpu_to_processor( 200 int cpu); 201 202/* Lock macros */ 203 204#define pset_lock(p) simple_lock(&(p)->sched_lock) 205#define pset_unlock(p) simple_unlock(&(p)->sched_lock) 206#define pset_lock_init(p) simple_lock_init(&(p)->sched_lock, 0) 207 208/* Update hints */ 209 210#define pset_pri_hint(ps, p, pri) \ 211MACRO_BEGIN \ 212 if ((p) != (ps)->low_pri) { \ 213 if ((pri) < (ps)->low_pri->current_pri) \ 214 (ps)->low_pri = (p); \ 215 else \ 216 if ((ps)->low_pri->state < PROCESSOR_IDLE) \ 217 (ps)->low_pri = (p); \ 218 } \ 219MACRO_END 220 221#define pset_count_hint(ps, p, cnt) \ 222MACRO_BEGIN \ 223 if ((p) != (ps)->low_count) { \ 224 if ((cnt) < SCHED(processor_runq_count)((ps)->low_count)) \ 225 (ps)->low_count = (p); \ 226 else \ 227 if ((ps)->low_count->state < PROCESSOR_IDLE) \ 228 (ps)->low_count = (p); \ 229 } \ 230MACRO_END 231 232#define pset_pri_init_hint(ps, p) \ 233MACRO_BEGIN \ 234 (ps)->low_pri = (p); \ 235MACRO_END 236 237#define pset_count_init_hint(ps, p) \ 238MACRO_BEGIN \ 239 (ps)->low_count = (p); \ 240MACRO_END 241 242 243extern void processor_bootstrap(void); 244 245extern void processor_init( 246 processor_t processor, 247 int cpu_id, 248 processor_set_t processor_set); 249 250extern void processor_meta_init( 251 processor_t processor, 252 processor_t primary); 253 254extern kern_return_t processor_shutdown( 255 processor_t processor); 256 257extern void processor_queue_shutdown( 258 processor_t processor); 259 260extern processor_set_t processor_pset( 261 processor_t processor); 262 263extern pset_node_t pset_node_root(void); 264 265extern processor_set_t pset_create( 266 pset_node_t node); 267 268extern void pset_init( 269 processor_set_t pset, 270 pset_node_t node); 271 272extern kern_return_t processor_info_count( 273 processor_flavor_t flavor, 274 mach_msg_type_number_t *count); 275 276#define pset_deallocate(x) 277#define pset_reference(x) 278 279extern void machine_run_count( 280 uint32_t count); 281 282extern boolean_t machine_processor_is_inactive( 283 processor_t processor); 284 285extern processor_t machine_choose_processor( 286 processor_set_t pset, 287 processor_t processor); 288 289#else /* MACH_KERNEL_PRIVATE */ 290 291__BEGIN_DECLS 292 293extern void pset_deallocate( 294 processor_set_t pset); 295 296extern void pset_reference( 297 processor_set_t pset); 298 299__END_DECLS 300 301#endif /* MACH_KERNEL_PRIVATE */ 302 303#endif /* _KERN_PROCESSOR_H_ */ 304