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