|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University. ! 4: * Copyright (c) 1993,1994 The University of Utah and ! 5: * the Computer Systems Laboratory (CSL). ! 6: * All rights reserved. ! 7: * ! 8: * Permission to use, copy, modify and distribute this software and its ! 9: * documentation is hereby granted, provided that both the copyright ! 10: * notice and this permission notice appear in all copies of the ! 11: * software, derivative works or modified versions, and any portions ! 12: * thereof, and that both notices appear in supporting documentation. ! 13: * ! 14: * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF ! 15: * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY ! 16: * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF ! 17: * THIS SOFTWARE. ! 18: * ! 19: * Carnegie Mellon requests users of this software to return to ! 20: * ! 21: * Software Distribution Coordinator or [email protected] ! 22: * School of Computer Science ! 23: * Carnegie Mellon University ! 24: * Pittsburgh PA 15213-3890 ! 25: * ! 26: * any improvements or extensions that they make and grant Carnegie Mellon ! 27: * the rights to redistribute these changes. ! 28: */ ! 29: /* ! 30: * processor.h: Processor and processor-set definitions. ! 31: */ ! 32: ! 33: #ifndef _KERN_PROCESSOR_H_ ! 34: #define _KERN_PROCESSOR_H_ ! 35: ! 36: /* ! 37: * Data structures for managing processors and sets of processors. ! 38: */ ! 39: ! 40: #include <cpus.h> ! 41: #include <mach_fixpri.h> ! 42: #include <mach_host.h> ! 43: ! 44: #include <mach/boolean.h> ! 45: #include <mach/kern_return.h> ! 46: #include <mach/port.h> ! 47: #include <mach/processor_info.h> ! 48: #include <kern/cpu_number.h> ! 49: #include <kern/lock.h> ! 50: #include <kern/queue.h> ! 51: #include <kern/sched.h> ! 52: #include <kern/kern_types.h> ! 53: #include <kern/host.h> ! 54: ! 55: #if NCPUS > 1 ! 56: #include <machine/ast_types.h> ! 57: #endif /* NCPUS > 1 */ ! 58: ! 59: struct processor_set { ! 60: struct run_queue runq; /* runq for this set */ ! 61: queue_head_t idle_queue; /* idle processors */ ! 62: int idle_count; /* how many ? */ ! 63: decl_simple_lock_data(, idle_lock) /* lock for above */ ! 64: queue_head_t processors; /* all processors here */ ! 65: int processor_count; /* how many ? */ ! 66: boolean_t empty; /* true if no processors */ ! 67: queue_head_t tasks; /* tasks assigned */ ! 68: int task_count; /* how many */ ! 69: queue_head_t threads; /* threads in this set */ ! 70: int thread_count; /* how many */ ! 71: int ref_count; /* structure ref count */ ! 72: decl_simple_lock_data(, ref_lock) /* lock for ref count */ ! 73: queue_chain_t all_psets; /* link for all_psets */ ! 74: boolean_t active; /* is pset in use */ ! 75: decl_simple_lock_data(, lock) /* lock for everything else */ ! 76: struct ipc_port * pset_self; /* port for operations */ ! 77: struct ipc_port * pset_name_self; /* port for information */ ! 78: int max_priority; /* maximum priority */ ! 79: #if MACH_FIXPRI ! 80: int policies; /* bit vector for policies */ ! 81: #endif /* MACH_FIXPRI */ ! 82: int set_quantum; /* current default quantum */ ! 83: #if NCPUS > 1 ! 84: int quantum_adj_index; /* runtime quantum adj. */ ! 85: decl_simple_lock_data(, quantum_adj_lock) /* lock for above */ ! 86: int machine_quantum[NCPUS+1]; /* ditto */ ! 87: #endif /* NCPUS > 1 */ ! 88: long mach_factor; /* mach_factor */ ! 89: long load_average; /* load_average */ ! 90: long sched_load; /* load avg for scheduler */ ! 91: }; ! 92: extern struct processor_set default_pset; ! 93: ! 94: struct processor { ! 95: struct run_queue runq; /* local runq for this processor */ ! 96: /* XXX want to do this round robin eventually */ ! 97: queue_chain_t processor_queue; /* idle/assign/shutdown queue link */ ! 98: int state; /* See below */ ! 99: struct thread *next_thread; /* next thread to run if dispatched */ ! 100: struct thread *idle_thread; /* this processor's idle thread. */ ! 101: int quantum; /* quantum for current thread */ ! 102: boolean_t first_quantum; /* first quantum in succession */ ! 103: int last_quantum; /* last quantum assigned */ ! 104: ! 105: processor_set_t processor_set; /* processor set I belong to */ ! 106: processor_set_t processor_set_next; /* set I will belong to */ ! 107: queue_chain_t processors; /* all processors in set */ ! 108: decl_simple_lock_data(, lock) ! 109: struct ipc_port *processor_self; /* port for operations */ ! 110: int slot_num; /* machine-indep slot number */ ! 111: #if NCPUS > 1 ! 112: ast_check_t ast_check_data; /* for remote ast_check invocation */ ! 113: #endif /* NCPUS > 1 */ ! 114: /* punt id data temporarily */ ! 115: }; ! 116: typedef struct processor Processor; ! 117: extern struct processor processor_array[NCPUS]; ! 118: ! 119: /* ! 120: * Chain of all processor sets. ! 121: */ ! 122: extern queue_head_t all_psets; ! 123: extern int all_psets_count; ! 124: decl_simple_lock_data(extern, all_psets_lock); ! 125: ! 126: /* ! 127: * The lock ordering is: ! 128: * ! 129: * all_psets_lock ! 130: * | ! 131: * | ! 132: * V ! 133: * pset_lock ! 134: * | ! 135: * +-----------+---------------+-------------------+ ! 136: * | | | | ! 137: * | | | | ! 138: * | | V V ! 139: * | | task_lock pset_self->ip_lock ! 140: * | | | | ! 141: * | | +-----------+---------------+ | ! 142: * | | | | | ! 143: * | V V V V ! 144: * | thread_lock* pset_ref_lock ! 145: * | | ! 146: * | +-------+ ! 147: * | | | ! 148: * | | V ! 149: * | | runq_lock* ! 150: * | | ! 151: * V V ! 152: * processor_lock* ! 153: * | ! 154: * | ! 155: * V ! 156: * pset_idle_lock* ! 157: * | ! 158: * | ! 159: * V ! 160: * action_lock* ! 161: * ! 162: * Locks marked with "*" are taken at splsched. ! 163: */ ! 164: ! 165: /* ! 166: * XXX need a pointer to the master processor structure ! 167: */ ! 168: ! 169: extern processor_t master_processor; ! 170: ! 171: /* ! 172: * NOTE: The processor->processor_set link is needed in one of the ! 173: * scheduler's critical paths. [Figure out where to look for another ! 174: * thread to run on this processor.] It is accessed without locking. ! 175: * The following access protocol controls this field. ! 176: * ! 177: * Read from own processor - just read. ! 178: * Read from another processor - lock processor structure during read. ! 179: * Write from own processor - lock processor structure during write. ! 180: * Write from another processor - NOT PERMITTED. ! 181: * ! 182: */ ! 183: ! 184: /* ! 185: * Processor state locking: ! 186: * ! 187: * Values for the processor state are defined below. If the processor ! 188: * is off-line or being shutdown, then it is only necessary to lock ! 189: * the processor to change its state. Otherwise it is only necessary ! 190: * to lock its processor set's idle_lock. Scheduler code will ! 191: * typically lock only the idle_lock, but processor manipulation code ! 192: * will often lock both. ! 193: */ ! 194: ! 195: #define PROCESSOR_OFF_LINE 0 /* Not in system */ ! 196: #define PROCESSOR_RUNNING 1 /* Running normally */ ! 197: #define PROCESSOR_IDLE 2 /* idle */ ! 198: #define PROCESSOR_DISPATCHING 3 /* dispatching (idle -> running) */ ! 199: #define PROCESSOR_ASSIGN 4 /* Assignment is changing */ ! 200: #define PROCESSOR_SHUTDOWN 5 /* Being shutdown */ ! 201: ! 202: /* ! 203: * Use processor ptr array to find current processor's data structure. ! 204: * This replaces a multiplication (index into processor_array) with ! 205: * an array lookup and a memory reference. It also allows us to save ! 206: * space if processor numbering gets too sparse. ! 207: */ ! 208: ! 209: extern processor_t processor_ptr[NCPUS]; ! 210: ! 211: #define cpu_to_processor(i) (processor_ptr[i]) ! 212: ! 213: #define current_processor() (processor_ptr[cpu_number()]) ! 214: #define current_processor_set() (current_processor()->processor_set) ! 215: ! 216: /* Compatibility -- will go away */ ! 217: ! 218: #define cpu_state(slot_num) (processor_ptr[slot_num]->state) ! 219: #define cpu_idle(slot_num) (cpu_state(slot_num) == PROCESSOR_IDLE) ! 220: ! 221: /* Useful lock macros */ ! 222: ! 223: #define pset_lock(pset) simple_lock(&(pset)->lock) ! 224: #define pset_unlock(pset) simple_unlock(&(pset)->lock) ! 225: #define pset_ref_lock(pset) simple_lock(&(pset)->ref_lock) ! 226: #define pset_ref_unlock(pset) simple_unlock(&(pset)->ref_lock) ! 227: ! 228: #define processor_lock(pr) simple_lock(&(pr)->lock) ! 229: #define processor_unlock(pr) simple_unlock(&(pr)->lock) ! 230: ! 231: typedef mach_port_t *processor_array_t; ! 232: typedef mach_port_t *processor_set_array_t; ! 233: typedef mach_port_t *processor_set_name_array_t; ! 234: ! 235: ! 236: /* ! 237: * Exported functions ! 238: */ ! 239: ! 240: /* Initialization */ ! 241: ! 242: #ifdef KERNEL ! 243: #if MACH_HOST ! 244: extern void pset_sys_bootstrap(void); ! 245: extern void pset_sys_init(void); ! 246: #endif /* MACH_HOST */ ! 247: ! 248: /* Pset internal functions */ ! 249: ! 250: extern void pset_reference(processor_set_t); ! 251: extern void pset_deallocate(processor_set_t); ! 252: extern void pset_remove_processor(processor_set_t, processor_t); ! 253: extern void pset_add_processor(processor_set_t, processor_t); ! 254: extern void pset_remove_task(processor_set_t, struct task *); ! 255: extern void pset_add_task(processor_set_t, struct task *); ! 256: extern void pset_remove_thread(processor_set_t, struct thread *); ! 257: extern void pset_add_thread(processor_set_t, struct thread *); ! 258: extern void thread_change_psets(struct thread *, ! 259: processor_set_t, processor_set_t); ! 260: ! 261: /* Processor interface */ ! 262: ! 263: extern kern_return_t processor_get_assignment( ! 264: processor_t processor, ! 265: processor_set_t *processor_set); ! 266: ! 267: extern kern_return_t processor_info( ! 268: processor_t processor, ! 269: int flavor, ! 270: host_t * host, ! 271: processor_info_t info, ! 272: natural_t * count); ! 273: ! 274: extern kern_return_t processor_start( ! 275: processor_t processor); ! 276: ! 277: extern kern_return_t processor_exit( ! 278: processor_t processor); ! 279: ! 280: extern kern_return_t processor_control( ! 281: processor_t processor, ! 282: processor_info_t info, ! 283: natural_t count); ! 284: ! 285: /* Pset interface */ ! 286: ! 287: extern kern_return_t processor_set_create( ! 288: host_t host, ! 289: processor_set_t *new_set, ! 290: processor_set_t *new_name); ! 291: ! 292: extern kern_return_t processor_set_destroy( ! 293: processor_set_t pset); ! 294: ! 295: extern kern_return_t processor_set_info( ! 296: processor_set_t pset, ! 297: int flavor, ! 298: host_t *host, ! 299: processor_set_info_t info, ! 300: natural_t *count); ! 301: ! 302: extern kern_return_t processor_set_max_priority( ! 303: processor_set_t pset, ! 304: int max_priority, ! 305: boolean_t change_threads); ! 306: ! 307: extern kern_return_t processor_set_policy_enable( ! 308: processor_set_t pset, ! 309: int policy); ! 310: ! 311: extern kern_return_t processor_set_policy_disable( ! 312: processor_set_t pset, ! 313: int policy, ! 314: boolean_t change_threads); ! 315: ! 316: extern kern_return_t processor_set_tasks( ! 317: processor_set_t pset, ! 318: task_array_t *task_list, ! 319: natural_t *count); ! 320: ! 321: extern kern_return_t processor_set_threads( ! 322: processor_set_t pset, ! 323: thread_array_t *thread_list, ! 324: natural_t *count); ! 325: #endif ! 326: ! 327: #endif /* _KERN_PROCESSOR_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.