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