|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1993-1987 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * File: thread.h ! 28: * Author: Avadis Tevanian, Jr. ! 29: * ! 30: * This file contains the structure definitions for threads. ! 31: * ! 32: */ ! 33: ! 34: #ifndef _KERN_THREAD_H_ ! 35: #define _KERN_THREAD_H_ ! 36: ! 37: #include <mach_ipc_compat.h> ! 38: #include <hw_footprint.h> ! 39: #include <mach_fixpri.h> ! 40: #include <mach_host.h> ! 41: #include <net_atm.h> ! 42: ! 43: #include <mach/boolean.h> ! 44: #include <mach/thread_info.h> ! 45: #include <mach/thread_status.h> ! 46: #include <mach/machine/vm_types.h> ! 47: #include <mach/message.h> ! 48: #include <mach/port.h> ! 49: #include <mach/vm_prot.h> ! 50: #include <kern/ast.h> ! 51: #include <kern/cpu_number.h> ! 52: #include <kern/queue.h> ! 53: #include <kern/pc_sample.h> ! 54: #include <kern/processor.h> ! 55: #include <kern/sched_prim.h> /* event_t, continuation_t */ ! 56: #include <kern/time_out.h> ! 57: #include <kern/timer.h> ! 58: #include <kern/lock.h> ! 59: #include <kern/sched.h> ! 60: #include <kern/task.h> /* for current_space(), current_map() */ ! 61: #include <machine/thread.h> ! 62: #include <ipc/ipc_kmsg_queue.h> ! 63: ! 64: struct thread { ! 65: /* Run queues */ ! 66: queue_chain_t links; /* current run queue links */ ! 67: run_queue_t runq; /* run queue p is on SEE BELOW */ ! 68: /* ! 69: * NOTE: The runq field in the thread structure has an unusual ! 70: * locking protocol. If its value is RUN_QUEUE_NULL, then it is ! 71: * locked by the thread_lock, but if its value is something else ! 72: * (i.e. a run_queue) then it is locked by that run_queue's lock. ! 73: */ ! 74: ! 75: /* Task information */ ! 76: task_t task; /* Task to which I belong */ ! 77: queue_chain_t thread_list; /* list of threads in task */ ! 78: ! 79: /* Thread bookkeeping */ ! 80: queue_chain_t pset_threads; /* list of all threads in proc set*/ ! 81: ! 82: /* Self-preservation */ ! 83: decl_simple_lock_data(,lock) ! 84: int ref_count; /* number of references to me */ ! 85: ! 86: /* Hardware state */ ! 87: pcb_t pcb; /* hardware pcb & machine state */ ! 88: vm_offset_t kernel_stack; /* accurate only if the thread is ! 89: not swapped and not executing */ ! 90: vm_offset_t stack_privilege;/* reserved kernel stack */ ! 91: ! 92: /* Swapping information */ ! 93: void (*swap_func)(); /* start here after swapin */ ! 94: ! 95: /* Blocking information */ ! 96: event_t wait_event; /* event we are waiting on */ ! 97: int suspend_count; /* internal use only */ ! 98: kern_return_t wait_result; /* outcome of wait - ! 99: may be examined by this thread ! 100: WITHOUT locking */ ! 101: boolean_t wake_active; /* someone is waiting for this ! 102: thread to become suspended */ ! 103: int state; /* Thread state: */ ! 104: /* ! 105: * Thread states [bits or'ed] ! 106: */ ! 107: #define TH_WAIT 0x01 /* thread is queued for waiting */ ! 108: #define TH_SUSP 0x02 /* thread has been asked to stop */ ! 109: #define TH_RUN 0x04 /* thread is running or on runq */ ! 110: #define TH_UNINT 0x08 /* thread is waiting uninteruptibly */ ! 111: #define TH_HALTED 0x10 /* thread is halted at clean point ? */ ! 112: ! 113: #define TH_IDLE 0x80 /* thread is an idle thread */ ! 114: ! 115: #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT) ! 116: ! 117: #define TH_SWAPPED 0x0100 /* thread has no kernel stack */ ! 118: #define TH_SW_COMING_IN 0x0200 /* thread is waiting for kernel stack */ ! 119: ! 120: #define TH_SWAP_STATE (TH_SWAPPED | TH_SW_COMING_IN) ! 121: ! 122: /* Scheduling information */ ! 123: int priority; /* thread's priority */ ! 124: int max_priority; /* maximum priority */ ! 125: int sched_pri; /* scheduled (computed) priority */ ! 126: #if MACH_FIXPRI ! 127: int sched_data; /* for use by policy */ ! 128: int policy; /* scheduling policy */ ! 129: #endif /* MACH_FIXPRI */ ! 130: int depress_priority; /* depressed from this priority */ ! 131: unsigned int cpu_usage; /* exp. decaying cpu usage [%cpu] */ ! 132: unsigned int sched_usage; /* load-weighted cpu usage [sched] */ ! 133: unsigned int sched_stamp; /* last time priority was updated */ ! 134: ! 135: /* VM global variables */ ! 136: ! 137: vm_offset_t recover; /* page fault recovery (copyin/out) */ ! 138: boolean_t vm_privilege; /* Can use reserved memory? */ ! 139: ! 140: /* User-visible scheduling state */ ! 141: int user_stop_count; /* outstanding stops */ ! 142: ! 143: /* IPC data structures */ ! 144: struct thread *ith_next, *ith_prev; ! 145: mach_msg_return_t ith_state; ! 146: union { ! 147: mach_msg_size_t msize; /* max size for recvd msg */ ! 148: struct ipc_kmsg *kmsg; /* received message */ ! 149: } data; ! 150: mach_port_seqno_t ith_seqno; /* seqno of recvd message */ ! 151: ! 152: /* This queue is used only when destroying messages: ! 153: it prevents nasty recursion problems when destroying one message ! 154: causes other messages to be destroyed. ! 155: This queue should always be empty under normal circumstances. ! 156: See ipc_kmsg_destroy() for more details. */ ! 157: struct ipc_kmsg_queue ith_messages; ! 158: ! 159: decl_simple_lock_data(, ith_lock_data) ! 160: struct ipc_port *ith_self; /* not a right, doesn't hold ref */ ! 161: struct ipc_port *ith_sself; /* a send right */ ! 162: struct ipc_port *ith_exception; /* a send right */ ! 163: #if MACH_IPC_COMPAT ! 164: struct ipc_port *ith_reply; /* a send right */ ! 165: #endif /* MACH_IPC_COMPAT */ ! 166: ! 167: mach_port_t ith_mig_reply; /* reply port for mig */ ! 168: struct ipc_port *ith_rpc_reply; /* reply port for kernel RPCs */ ! 169: ! 170: /* State saved when thread's stack is discarded */ ! 171: union { ! 172: struct { ! 173: mach_msg_header_t *msg; ! 174: mach_msg_option_t option; ! 175: mach_msg_size_t rcv_size; ! 176: mach_msg_timeout_t timeout; ! 177: mach_port_t notify; ! 178: struct ipc_object *object; ! 179: struct ipc_mqueue *mqueue; ! 180: } receive; ! 181: struct { ! 182: struct ipc_port *port; ! 183: int exc; ! 184: int code; ! 185: int subcode; ! 186: } exception; ! 187: void *other; /* catch-all for other state */ ! 188: } saved; ! 189: ! 190: /* Timing data structures */ ! 191: timer_data_t user_timer; /* user mode timer */ ! 192: timer_data_t system_timer; /* system mode timer */ ! 193: timer_save_data_t user_timer_save; /* saved user timer value */ ! 194: timer_save_data_t system_timer_save; /* saved sys timer val. */ ! 195: unsigned int cpu_delta; /* cpu usage since last update */ ! 196: unsigned int sched_delta; /* weighted cpu usage since update */ ! 197: ! 198: /* Creation time stamp */ ! 199: time_value_t creation_time; ! 200: ! 201: /* Time-outs */ ! 202: timer_elt_data_t timer; /* timer for thread */ ! 203: timer_elt_data_t depress_timer; /* timer for priority depression */ ! 204: ! 205: /* Ast/Halt data structures */ ! 206: boolean_t active; /* how alive is the thread */ ! 207: int ast; /* ast's needed. See ast.h */ ! 208: ! 209: /* Processor data structures */ ! 210: processor_set_t processor_set; /* assigned processor set */ ! 211: processor_t bound_processor; /* bound to processor ?*/ ! 212: ! 213: sample_control_t pc_sample; ! 214: ! 215: #if MACH_HOST ! 216: boolean_t may_assign; /* may assignment change? */ ! 217: boolean_t assign_active; /* someone waiting for may_assign */ ! 218: #endif /* MACH_HOST */ ! 219: ! 220: #if NCPUS > 1 ! 221: processor_t last_processor; /* processor this last ran on */ ! 222: #endif /* NCPUS > 1 */ ! 223: ! 224: #if NET_ATM ! 225: nw_ep_owned_t nw_ep_waited; ! 226: #endif /* NET_ATM */ ! 227: }; ! 228: ! 229: /* typedef of thread_t is in kern/kern_types.h */ ! 230: typedef struct thread_shuttle *thread_shuttle_t; ! 231: #define THREAD_NULL ((thread_t) 0) ! 232: #define THREAD_SHUTTLE_NULL ((thread_shuttle_t)0) ! 233: ! 234: #define ith_msize data.msize ! 235: #define ith_kmsg data.kmsg ! 236: #define ith_wait_result wait_result ! 237: ! 238: #define ith_msg saved.receive.msg ! 239: #define ith_option saved.receive.option ! 240: #define ith_rcv_size saved.receive.rcv_size ! 241: #define ith_timeout saved.receive.timeout ! 242: #define ith_notify saved.receive.notify ! 243: #define ith_object saved.receive.object ! 244: #define ith_mqueue saved.receive.mqueue ! 245: ! 246: #define ith_port saved.exception.port ! 247: #define ith_exc saved.exception.exc ! 248: #define ith_exc_code saved.exception.code ! 249: #define ith_exc_subcode saved.exception.subcode ! 250: ! 251: #define ith_other saved.other ! 252: ! 253: #ifndef _KERN_KERN_TYPES_H_ ! 254: typedef struct thread *thread_t; ! 255: ! 256: #define THREAD_NULL ((thread_t) 0) ! 257: ! 258: typedef mach_port_t *thread_array_t; ! 259: #endif /* _KERN_KERN_TYPES_H_ */ ! 260: ! 261: ! 262: extern thread_t active_threads[NCPUS]; /* active threads */ ! 263: extern vm_offset_t active_stacks[NCPUS]; /* active kernel stacks */ ! 264: ! 265: #ifdef KERNEL ! 266: /* ! 267: * User routines ! 268: */ ! 269: ! 270: extern kern_return_t thread_create( ! 271: task_t parent_task, ! 272: thread_t *child_thread); ! 273: extern kern_return_t thread_terminate( ! 274: thread_t thread); ! 275: extern kern_return_t thread_suspend( ! 276: thread_t thread); ! 277: extern kern_return_t thread_resume( ! 278: thread_t thread); ! 279: extern kern_return_t thread_abort( ! 280: thread_t thread); ! 281: extern kern_return_t thread_get_state( ! 282: thread_t thread, ! 283: int flavor, ! 284: thread_state_t old_state, ! 285: natural_t *old_state_count); ! 286: extern kern_return_t thread_set_state( ! 287: thread_t thread, ! 288: int flavor, ! 289: thread_state_t new_state, ! 290: natural_t new_state_count); ! 291: extern kern_return_t thread_get_special_port( ! 292: thread_t thread, ! 293: int which, ! 294: struct ipc_port **portp); ! 295: extern kern_return_t thread_set_special_port( ! 296: thread_t thread, ! 297: int which, ! 298: struct ipc_port *port); ! 299: extern kern_return_t thread_info( ! 300: thread_t thread, ! 301: int flavor, ! 302: thread_info_t thread_info_out, ! 303: natural_t *thread_info_count); ! 304: extern kern_return_t thread_assign( ! 305: thread_t thread, ! 306: processor_set_t new_pset); ! 307: extern kern_return_t thread_assign_default( ! 308: thread_t thread); ! 309: #endif ! 310: ! 311: /* ! 312: * Kernel-only routines ! 313: */ ! 314: ! 315: extern void thread_init(void); ! 316: extern void thread_reference(thread_t); ! 317: extern void thread_deallocate(thread_t); ! 318: extern void thread_hold(thread_t); ! 319: extern kern_return_t thread_dowait( ! 320: thread_t thread, ! 321: boolean_t must_halt); ! 322: extern void thread_release(thread_t); ! 323: extern kern_return_t thread_halt( ! 324: thread_t thread, ! 325: boolean_t must_halt); ! 326: extern void thread_halt_self(void); ! 327: extern void thread_force_terminate(thread_t); ! 328: extern void thread_set_own_priority( ! 329: int priority); ! 330: extern thread_t kernel_thread( ! 331: task_t task, ! 332: void (*start)(void), ! 333: void * arg); ! 334: ! 335: extern void reaper_thread(void); ! 336: ! 337: #if MACH_HOST ! 338: extern void thread_freeze( ! 339: thread_t thread); ! 340: extern void thread_doassign( ! 341: thread_t thread, ! 342: processor_set_t new_pset, ! 343: boolean_t release_freeze); ! 344: extern void thread_unfreeze( ! 345: thread_t thread); ! 346: #endif /* MACH_HOST */ ! 347: ! 348: /* ! 349: * Macro-defined routines ! 350: */ ! 351: ! 352: #define thread_pcb(th) ((th)->pcb) ! 353: ! 354: #define thread_lock(th) simple_lock(&(th)->lock) ! 355: #define thread_unlock(th) simple_unlock(&(th)->lock) ! 356: ! 357: #define thread_should_halt(thread) \ ! 358: ((thread)->ast & (AST_HALT|AST_TERMINATE)) ! 359: ! 360: /* ! 361: * Machine specific implementations of the current thread macro ! 362: * designate this by defining CURRENT_THREAD. ! 363: */ ! 364: #ifndef CURRENT_THREAD ! 365: #define current_thread() (active_threads[cpu_number()]) ! 366: #endif /* CURRENT_THREAD */ ! 367: ! 368: #define current_stack() (active_stacks[cpu_number()]) ! 369: ! 370: #define current_task() (current_thread()->task) ! 371: #define current_space() (current_task()->itk_space) ! 372: #define current_map() (current_task()->map) ! 373: ! 374: #endif /* _KERN_THREAD_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.