|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_FREE_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University ! 28: * All Rights Reserved. ! 29: * ! 30: * Permission to use, copy, modify and distribute this software and its ! 31: * documentation is hereby granted, provided that both the copyright ! 32: * notice and this permission notice appear in all copies of the ! 33: * software, derivative works or modified versions, and any portions ! 34: * thereof, and that both notices appear in supporting documentation. ! 35: * ! 36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 39: * ! 40: * Carnegie Mellon requests users of this software to return to ! 41: * ! 42: * Software Distribution Coordinator or [email protected] ! 43: * School of Computer Science ! 44: * Carnegie Mellon University ! 45: * Pittsburgh PA 15213-3890 ! 46: * ! 47: * any improvements or extensions that they make and grant Carnegie Mellon ! 48: * the rights to redistribute these changes. ! 49: */ ! 50: /* ! 51: */ ! 52: /* ! 53: * File: thread.h ! 54: * Author: Avadis Tevanian, Jr. ! 55: * ! 56: * This file contains the structure definitions for threads. ! 57: * ! 58: */ ! 59: /* ! 60: * Copyright (c) 1993 The University of Utah and ! 61: * the Computer Systems Laboratory (CSL). All rights reserved. ! 62: * ! 63: * Permission to use, copy, modify and distribute this software and its ! 64: * documentation is hereby granted, provided that both the copyright ! 65: * notice and this permission notice appear in all copies of the ! 66: * software, derivative works or modified versions, and any portions ! 67: * thereof, and that both notices appear in supporting documentation. ! 68: * ! 69: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS ! 70: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF ! 71: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 72: * ! 73: * CSL requests users of this software to return to [email protected] any ! 74: * improvements that they make and grant CSL redistribution rights. ! 75: * ! 76: */ ! 77: ! 78: #ifndef _KERN_THREAD_H_ ! 79: #define _KERN_THREAD_H_ ! 80: ! 81: #include <mach/kern_return.h> ! 82: #include <mach/mach_types.h> ! 83: #include <mach/message.h> ! 84: #include <mach/boolean.h> ! 85: #include <mach/vm_types.h> ! 86: #include <mach/vm_prot.h> ! 87: #include <mach/thread_info.h> ! 88: #include <mach/thread_status.h> ! 89: #include <kern/cpu_data.h> /* for current_thread */ ! 90: #include <kern/kern_types.h> ! 91: ! 92: /* ! 93: * Logically, a thread of control consists of two parts: ! 94: * a thread_shuttle, which may migrate during an RPC, and ! 95: * a thread_activation, which remains attached to a task. ! 96: * The thread_shuttle is the larger portion of the two-part thread, ! 97: * and contains scheduling info, messaging support, accounting info, ! 98: * and links to the thread_activation within which the shuttle is ! 99: * currently operating. ! 100: * ! 101: * It might make sense to have the thread_shuttle be a proper sub-structure ! 102: * of the thread, with the thread containing links to both the shuttle and ! 103: * activation. In order to reduce the scope and complexity of source ! 104: * changes and the overhead of maintaining these linkages, we have subsumed ! 105: * the shuttle into the thread, calling it a thread_shuttle. ! 106: * ! 107: * User accesses to threads always come in via the user's thread port, ! 108: * which gets translated to a pointer to the target thread_activation. ! 109: * Kernel accesses intended to effect the entire thread, typically use ! 110: * a pointer to the thread_shuttle (current_thread()) as the target of ! 111: * their operations. This makes sense given that we have subsumed the ! 112: * shuttle into the thread_shuttle, eliminating one set of linkages. ! 113: * Operations effecting only the shuttle may use a thread_shuttle_t ! 114: * to indicate this. ! 115: * ! 116: * The current_act() macro returns a pointer to the current thread_act, while ! 117: * the current_thread() macro returns a pointer to the currently active ! 118: * thread_shuttle (representing the thread in its entirety). ! 119: */ ! 120: ! 121: /* ! 122: * Possible results of thread_block - returned in ! 123: * current_thread()->wait_result. ! 124: */ ! 125: #define THREAD_AWAKENED 0 /* normal wakeup */ ! 126: #define THREAD_TIMED_OUT 1 /* timeout expired */ ! 127: #define THREAD_INTERRUPTED 2 /* interrupted by clear_wait */ ! 128: #define THREAD_RESTART 3 /* restart operation entirely */ ! 129: ! 130: /* ! 131: * Interruptible flags for assert_wait ! 132: * ! 133: */ ! 134: #define THREAD_UNINT 0 /* not interruptible */ ! 135: #define THREAD_INTERRUPTIBLE 1 /* may not be restartable */ ! 136: #define THREAD_ABORTSAFE 2 /* abortable safely */ ! 137: ! 138: #ifdef MACH_KERNEL_PRIVATE ! 139: #include <cpus.h> ! 140: #include <hw_footprint.h> ! 141: #include <mach_host.h> ! 142: #include <mach_prof.h> ! 143: #include <dipc.h> ! 144: #include <xkmachkernel.h> ! 145: #include <mach_lock_mon.h> ! 146: #include <mach_ldebug.h> ! 147: ! 148: #include <mach/port.h> ! 149: #include <kern/ast.h> ! 150: #include <kern/cpu_number.h> ! 151: #include <kern/queue.h> ! 152: #include <kern/time_out.h> ! 153: #include <kern/timer.h> ! 154: #include <kern/lock.h> ! 155: #include <kern/sched.h> ! 156: #include <kern/sched_prim.h> ! 157: #include <kern/thread_pool.h> ! 158: #include <kern/thread_call.h> ! 159: #include <kern/thread_call_private.h> ! 160: #include <kern/task.h> ! 161: #include <ipc/ipc_kmsg.h> ! 162: #include <machine/thread.h> ! 163: ! 164: ! 165: typedef struct thread_shuttle { ! 166: /* ! 167: * Beginning of thread_shuttle proper. When the thread is on ! 168: * a wait queue, these three fields are in treated as an un- ! 169: * official union with a wait_queue_element. If you change ! 170: * these, you must change that definition as well. ! 171: */ ! 172: queue_chain_t links; /* current run/wait queue links */ ! 173: run_queue_t runq; /* run queue p is on SEE BELOW */ ! 174: int whichq; /* which queue level p is on */ ! 175: ! 176: /* ! 177: * NOTE: The runq field in the thread structure has an unusual ! 178: * locking protocol. If its value is RUN_QUEUE_NULL, then it is ! 179: * locked by the thread_lock, but if its value is something else ! 180: * (i.e. a run_queue) then it is locked by that run_queue's lock. ! 181: */ ! 182: ! 183: /* Thread bookkeeping */ ! 184: queue_chain_t pset_threads; /* list of all shuttles in proc set */ ! 185: ! 186: /* Self-preservation */ ! 187: decl_simple_lock_data(,lock) /* scheduling lock (thread_lock()) */ ! 188: decl_simple_lock_data(,wake_lock) /* covers wake_active (wake_lock())*/ ! 189: decl_mutex_data(,rpc_lock) /* RPC lock (rpc_lock()) */ ! 190: int ref_count; /* number of references to me */ ! 191: ! 192: vm_offset_t kernel_stack; /* accurate only if the thread is ! 193: not swapped and not executing */ ! 194: ! 195: vm_offset_t stack_privilege;/* reserved kernel stack */ ! 196: ! 197: /* Blocking information */ ! 198: int reason; /* why we blocked */ ! 199: event_t wait_event; /* event we are waiting on */ ! 200: kern_return_t wait_result; /* outcome of wait - ! 201: may be examined by this thread ! 202: WITHOUT locking */ ! 203: wait_queue_t wait_queue; /* wait queue we are currently on */ ! 204: queue_chain_t wait_link; /* event's wait queue link */ ! 205: boolean_t wake_active; /* Someone is waiting for this ! 206: thread to become suspended */ ! 207: int state; /* Thread state: */ ! 208: boolean_t preempt; /* Thread is undergoing preemption */ ! 209: ! 210: #if ETAP_EVENT_MONITOR ! 211: int etap_reason; /* real reason why we blocked */ ! 212: boolean_t etap_trace; /* ETAP trace status */ ! 213: #endif /* ETAP_EVENT_MONITOR */ ! 214: ! 215: /* ! 216: * Thread states [bits or'ed] ! 217: */ ! 218: #define TH_WAIT 0x01 /* thread is queued for waiting */ ! 219: #define TH_SUSP 0x02 /* thread has been asked to stop */ ! 220: #define TH_RUN 0x04 /* thread is running or on runq */ ! 221: #define TH_UNINT 0x08 /* thread is waiting uninteruptibly */ ! 222: #define TH_HALTED 0x10 /* thread is halted at clean point ? */ ! 223: ! 224: #define TH_ABORT 0x20 /* abort interruptible waits */ ! 225: #define TH_SWAPPED_OUT 0x40 /* thread is swapped out */ ! 226: ! 227: #define TH_IDLE 0x80 /* thread is an idle thread */ ! 228: ! 229: #define TH_SCHED_STATE (TH_WAIT|TH_SUSP|TH_RUN|TH_UNINT) ! 230: ! 231: #define TH_STACK_HANDOFF 0x0100 /* thread has no kernel stack */ ! 232: #define TH_STACK_COMING_IN 0x0200 /* thread is waiting for kernel stack */ ! 233: #define TH_STACK_STATE (TH_STACK_HANDOFF | TH_STACK_COMING_IN) ! 234: ! 235: #define TH_TERMINATE 0x400 /* thread is terminating */ ! 236: ! 237: #if 0 /* Grenoble version */ ! 238: int preempt; /* Thread preemption status */ ! 239: #define TH_PREEMPTABLE 0 /* Thread is preemptable */ ! 240: #define TH_NOT_PREEMPTABLE 1 /* Thread is not preemptable */ ! 241: #define TH_PREEMPTED 2 /* Thread has been preempted */ ! 242: ! 243: #if ETAP_EVENT_MONITOR ! 244: int etap_reason; /* real reason why we blocked */ ! 245: boolean_t etap_trace; /* ETAP trace status */ ! 246: #endif /* ETAP_EVENT_MONITOR */ ! 247: ! 248: #endif ! 249: ! 250: /* Stack handoff information */ ! 251: void (*continuation)(/* start here next time runnable */ ! 252: void); ! 253: int cont_arg; /* continuation argument */ ! 254: ! 255: /* Scheduling information */ ! 256: int policy; /* scheduling policy */ ! 257: sp_info_t sp_info; /* policy-specific information */ ! 258: int pending_policy; /* pending scheduling policy */ ! 259: sp_attributes_t pending_sched_attr; ! 260: /* policy-specific information */ ! 261: kern_return_t change_sfr; /* return value for pending change */ ! 262: int sched_pri; /* scheduled (computed) priority */ ! 263: unsigned int sleep_stamp; /* last time in TH_WAIT state */ ! 264: #if 0 /* Grenoble */ ! 265: unsigned int sched_change_stamp; ! 266: /* last time priority or policy was ! 267: explicitly changed (not the same ! 268: units as sched_stamp!) */ ! 269: int unconsumed_quantum; /* leftover quantum (RR/FIFO) */ ! 270: #endif ! 271: ! 272: /* VM global variables */ ! 273: boolean_t vm_privilege; /* can use reserved memory? */ ! 274: vm_offset_t recover; /* page fault recovery (copyin/out) */ ! 275: ! 276: /* IPC data structures */ ! 277: ! 278: struct ipc_kmsg_queue ith_messages; ! 279: ! 280: mach_port_t ith_mig_reply; /* reply port for mig */ ! 281: mach_port_t ith_rpc_reply; /* reply port for kernel RPCs */ ! 282: ! 283: /* Various bits of stashed state */ ! 284: union { ! 285: struct { ! 286: mach_msg_return_t state; /* receive state */ ! 287: mach_msg_size_t msize; /* max size for recvd msg */ ! 288: struct ipc_kmsg *kmsg; /* received message */ ! 289: mach_port_seqno_t seqno; /* seqno of recvd message */ ! 290: mach_msg_option_t option; ! 291: mach_msg_body_t *scatter_list; ! 292: mach_msg_size_t scatter_list_size; ! 293: } receive; ! 294: char *other; /* catch-all for other state */ ! 295: } saved; ! 296: ! 297: /* Timing data structures */ ! 298: timer_data_t user_timer; /* user mode timer */ ! 299: timer_data_t system_timer; /* system mode timer */ ! 300: timer_data_t depressed_timer;/* depressed priority timer */ ! 301: timer_save_data_t user_timer_save; /* saved user timer value */ ! 302: timer_save_data_t system_timer_save; /* saved sys timer val. */ ! 303: /*** ??? should the next two fields be moved to SP-specific struct?***/ ! 304: unsigned int cpu_delta; /* cpu usage since last update */ ! 305: unsigned int sched_delta; /* weighted cpu usage since update */ ! 306: ! 307: /* Timers for time-outs */ ! 308: thread_call_data_t wait_timer; ! 309: boolean_t wait_timer_is_set; ! 310: thread_call_data_t depress_timer; ! 311: ! 312: /* Ast/Halt data structures */ ! 313: boolean_t active; /* how alive is the thread */ ! 314: ! 315: /* Processor data structures */ ! 316: processor_set_t processor_set; /* assigned processor set */ ! 317: #if NCPUS > 1 ! 318: processor_t bound_processor; /* bound to processor ?*/ ! 319: #endif /* NCPUS > 1 */ ! 320: #if MACH_HOST ! 321: boolean_t may_assign; /* may assignment change? */ ! 322: boolean_t assign_active; /* someone waiting for may_assign */ ! 323: #endif /* MACH_HOST */ ! 324: ! 325: #if XKMACHKERNEL ! 326: int xk_type; ! 327: #endif /* XKMACHKERNEL */ ! 328: ! 329: #if NCPUS > 1 ! 330: processor_t last_processor; /* processor this last ran on */ ! 331: #if MACH_LOCK_MON ! 332: unsigned lock_stack; /* number of locks held */ ! 333: #endif /* MACH_LOCK_MON */ ! 334: #endif /* NCPUS > 1 */ ! 335: ! 336: int at_safe_point; /* thread_abort_safely allowed */ ! 337: int funnel_state; ! 338: #define TH_FN_OWNED 0x1 /* we own the funnel lock */ ! 339: #define TH_FN_REFUNNEL 0x2 /* must reaquire funnel lock when unblocking */ ! 340: ! 341: #if MACH_LDEBUG ! 342: /* ! 343: * Debugging: track acquired mutexes and locks. ! 344: * Because a thread can block while holding such ! 345: * synchronizers, we think of the thread as ! 346: * "owning" them. ! 347: */ ! 348: #define MUTEX_STACK_DEPTH 20 ! 349: #define LOCK_STACK_DEPTH 20 ! 350: mutex_t *mutex_stack[MUTEX_STACK_DEPTH]; ! 351: lock_t *lock_stack[LOCK_STACK_DEPTH]; ! 352: unsigned int mutex_stack_index; ! 353: unsigned int lock_stack_index; ! 354: unsigned mutex_count; /* XXX to be deleted XXX */ ! 355: boolean_t kthread; /* thread is a kernel thread */ ! 356: #endif /* MACH_LDEBUG */ ! 357: ! 358: /* ! 359: * End of thread_shuttle proper ! 360: */ ! 361: ! 362: /* ! 363: * Migration and thread_activation linkage information ! 364: */ ! 365: struct thread_activation *top_act; /* "current" thr_act */ ! 366: ! 367: } Thread_Shuttle; ! 368: ! 369: #define THREAD_SHUTTLE_NULL ((thread_shuttle_t)0) ! 370: ! 371: #define ith_state saved.receive.state ! 372: #define ith_msize saved.receive.msize ! 373: #define ith_kmsg saved.receive.kmsg ! 374: #define ith_seqno saved.receive.seqno ! 375: #define ith_option saved.receive.option ! 376: #define ith_scatter_list saved.receive.scatter_list ! 377: #define ith_scatter_list_size saved.receive.scatter_list_size ! 378: #define ith_other saved.other ! 379: ! 380: extern thread_act_t active_kloaded[NCPUS]; /* "" kernel-loaded acts */ ! 381: extern vm_offset_t active_stacks[NCPUS]; /* active kernel stacks */ ! 382: extern vm_offset_t kernel_stack[NCPUS]; ! 383: ! 384: decl_mutex_data(extern,funnel_lock); ! 385: ! 386: #ifndef MACHINE_STACK_STASH ! 387: /* ! 388: * MD Macro to fill up global stack state, ! 389: * keeping the MD structure sizes + games private ! 390: */ ! 391: #define MACHINE_STACK_STASH(stack) \ ! 392: MACRO_BEGIN \ ! 393: mp_disable_preemption(); \ ! 394: active_stacks[cpu_number()] = (stack); \ ! 395: kernel_stack[cpu_number()] = (stack) + KERNEL_STACK_SIZE; \ ! 396: mp_enable_preemption(); \ ! 397: MACRO_END ! 398: #endif /* MACHINE_STACK_STASH */ ! 399: ! 400: /* ! 401: * Kernel-only routines ! 402: */ ! 403: ! 404: /* Initialize thread module */ ! 405: extern void thread_init(void); ! 406: ! 407: /* Take reference on thread (make sure it doesn't go away) */ ! 408: extern void thread_reference( ! 409: thread_t thread); ! 410: ! 411: /* Release reference on thread */ ! 412: extern void thread_deallocate( ! 413: thread_t thread); ! 414: ! 415: /* Set priority of calling thread */ ! 416: extern void thread_set_own_priority( ! 417: int priority); ! 418: ! 419: /* Reset thread's priority */ ! 420: extern kern_return_t thread_priority( ! 421: thread_act_t thr_act, ! 422: int priority, ! 423: boolean_t set_max); ! 424: ! 425: /* Reset thread's max priority */ ! 426: extern kern_return_t thread_max_priority( ! 427: thread_act_t thr_act, ! 428: processor_set_t pset, ! 429: int max_priority); ! 430: ! 431: /* Reset thread's max priority while holding RPC locks */ ! 432: extern kern_return_t thread_max_priority_locked( ! 433: thread_t thread, ! 434: processor_set_t pset, ! 435: int max_priority); ! 436: ! 437: /* Set a thread's priority while holding RPC locks */ ! 438: extern kern_return_t thread_priority_locked( ! 439: thread_t thread, ! 440: int priority, ! 441: boolean_t set_max); ! 442: ! 443: /* Start a thread at specified routine */ ! 444: #define thread_start(thread, start) \ ! 445: (thread)->continuation = (start) ! 446: ! 447: ! 448: /* Reaps threads waiting to be destroyed */ ! 449: extern void thread_reaper(void); ! 450: ! 451: extern boolean_t thread_not_preemptable( ! 452: thread_t thread); ! 453: ! 454: #if MACH_HOST ! 455: /* Preclude thread processor set assignement */ ! 456: extern void thread_freeze( ! 457: thread_t thread); ! 458: ! 459: /* Assign thread to a processor set */ ! 460: extern void thread_doassign( ! 461: thread_t thread, ! 462: processor_set_t new_pset, ! 463: boolean_t release_freeze); ! 464: ! 465: /* Allow thread processor set assignement */ ! 466: extern void thread_unfreeze( ! 467: thread_t thread); ! 468: ! 469: #endif /* MACH_HOST */ ! 470: ! 471: /* Insure thread always has a kernel stack */ ! 472: extern void stack_privilege( ! 473: thread_t thread); ! 474: ! 475: extern void consider_thread_collect(void); ! 476: ! 477: /* ! 478: * Arguments to specify aggressiveness to thread halt. ! 479: * Can't have MUST_HALT and SAFELY at the same time. ! 480: */ ! 481: #define THREAD_HALT_NORMAL 0 ! 482: #define THREAD_HALT_MUST_HALT 1 /* no deadlock checks */ ! 483: #define THREAD_HALT_SAFELY 2 /* result must be restartable */ ! 484: ! 485: /* ! 486: * Macro-defined routines ! 487: */ ! 488: ! 489: #define thread_pcb(th) ((th)->pcb) ! 490: ! 491: #define thread_lock_init(th) \ ! 492: simple_lock_init(&(th)->lock, ETAP_THREAD_LOCK) ! 493: #define thread_lock(th) simple_lock(&(th)->lock) ! 494: #define thread_unlock(th) simple_unlock(&(th)->lock) ! 495: ! 496: #define thread_should_halt_fast(thread) \ ! 497: (!(thread)->top_act || \ ! 498: !(thread)->top_act->active || \ ! 499: (thread)->top_act->ast & (AST_HALT|AST_TERMINATE)) ! 500: ! 501: #define thread_should_halt(thread) thread_should_halt_fast(thread) ! 502: ! 503: #if 0 /* Gernoble */ ! 504: /* ! 505: * We consider a thread not preemptable if it is marked as either ! 506: * suspended, waiting or halted. ! 507: * XXX - when scheduling framework and such is done, the ! 508: * thread state check can be eliminated ! 509: */ ! 510: #define thread_not_preemptable(thread) \ ! 511: (((thread)->state & (TH_WAIT|TH_SUSP)) != 0) ! 512: ! 513: #endif ! 514: ! 515: #define thread_lock_pair(ta,tb) \ ! 516: MACRO_BEGIN \ ! 517: if ((ta) < (tb)) { \ ! 518: thread_lock(ta); \ ! 519: thread_lock(tb); \ ! 520: } \ ! 521: else { \ ! 522: thread_lock(tb); \ ! 523: thread_lock(ta); \ ! 524: } \ ! 525: MACRO_END ! 526: ! 527: #define thread_unlock_pair(ta,tb) \ ! 528: MACRO_BEGIN \ ! 529: if ((ta) < (tb)) { \ ! 530: thread_unlock(tb); \ ! 531: thread_unlock(ta); \ ! 532: } \ ! 533: else { \ ! 534: thread_unlock(ta); \ ! 535: thread_unlock (tb); \ ! 536: } \ ! 537: MACRO_END ! 538: ! 539: #define rpc_lock_init(th) mutex_init(&(th)->rpc_lock, ETAP_THREAD_RPC) ! 540: #define rpc_lock(th) mutex_lock(&(th)->rpc_lock) ! 541: #define rpc_lock_try(th) mutex_try(&(th)->rpc_lock) ! 542: #define rpc_unlock(th) mutex_unlock(&(th)->rpc_lock) ! 543: ! 544: /* ! 545: * Lock to cover wake_active only; like thread_lock(), is taken ! 546: * at splsched(). Used to avoid calling into scheduler with a ! 547: * thread_lock() held. Precedes thread_lock() (and other scheduling- ! 548: * related locks) in the system lock ordering. ! 549: */ ! 550: #define wake_lock_init(th) \ ! 551: simple_lock_init(&(th)->wake_lock, ETAP_THREAD_WAKE) ! 552: #define wake_lock(th) simple_lock(&(th)->wake_lock) ! 553: #define wake_unlock(th) simple_unlock(&(th)->wake_lock) ! 554: ! 555: static __inline__ vm_offset_t current_stack(void); ! 556: static __inline__ vm_offset_t ! 557: current_stack(void) ! 558: { ! 559: vm_offset_t ret; ! 560: ! 561: mp_disable_preemption(); ! 562: ret = active_stacks[cpu_number()]; ! 563: mp_enable_preemption(); ! 564: return ret; ! 565: } ! 566: ! 567: ! 568: extern void pcb_module_init(void); ! 569: ! 570: extern void pcb_init( ! 571: thread_act_t thr_act); ! 572: ! 573: extern void pcb_terminate( ! 574: thread_act_t thr_act); ! 575: ! 576: extern void pcb_collect( ! 577: thread_act_t thr_act); ! 578: ! 579: extern void pcb_user_to_kernel( ! 580: thread_act_t thr_act); ! 581: ! 582: extern kern_return_t thread_setstatus( ! 583: thread_act_t thr_act, ! 584: int flavor, ! 585: thread_state_t tstate, ! 586: mach_msg_type_number_t count); ! 587: ! 588: extern kern_return_t thread_getstatus( ! 589: thread_act_t thr_act, ! 590: int flavor, ! 591: thread_state_t tstate, ! 592: mach_msg_type_number_t *count); ! 593: ! 594: extern boolean_t stack_alloc_try( ! 595: thread_t thread, ! 596: void (*continuation)(void)); ! 597: ! 598: /* This routine now used only internally */ ! 599: extern kern_return_t thread_info_shuttle( ! 600: thread_act_t thr_act, ! 601: thread_flavor_t flavor, ! 602: thread_info_t thread_info_out, ! 603: mach_msg_type_number_t *thread_info_count); ! 604: ! 605: extern void thread_user_to_kernel( ! 606: thread_t thread); ! 607: ! 608: /* Machine-dependent routines */ ! 609: extern void thread_machine_init(void); ! 610: ! 611: extern void thread_machine_set_current( ! 612: thread_t thread ); ! 613: ! 614: extern kern_return_t thread_machine_create( ! 615: thread_t thread, ! 616: thread_act_t thr_act, ! 617: void (*start_pos)(void)); ! 618: ! 619: extern void thread_set_syscall_return( ! 620: thread_t thread, ! 621: kern_return_t retval); ! 622: ! 623: extern void thread_machine_destroy( ! 624: thread_t thread ); ! 625: ! 626: extern void thread_machine_flush( ! 627: thread_act_t thr_act); ! 628: ! 629: extern thread_t kernel_thread_with_attributes( ! 630: task_t task, ! 631: sp_attributes_t attributes, ! 632: void (*start_at)(void), ! 633: boolean_t start_running); ! 634: ! 635: #else /* !MACH_KERNEL_PRIVATE */ ! 636: ! 637: extern boolean_t thread_should_halt(thread_t); ! 638: ! 639: #endif /* !MACH_KERNEL_PRIVATE */ ! 640: ! 641: extern thread_t kernel_thread( ! 642: task_t task, ! 643: void (*start)(void)); ! 644: ! 645: extern void thread_terminate_self(void); ! 646: ! 647: extern boolean_t thread_get_funneled(void); ! 648: ! 649: extern boolean_t thread_set_funneled( ! 650: boolean_t funneled); ! 651: ! 652: extern void thread_set_cont_arg(int); ! 653: ! 654: extern int thread_get_cont_arg(void); ! 655: ! 656: /* JMM - These are only temporary */ ! 657: extern boolean_t is_thread_running(thread_t); /* True is TH_RUN */ ! 658: extern boolean_t is_thread_idle(thread_t); /* True is TH_IDLE */ ! 659: extern event_t get_thread_waitevent(thread_t); ! 660: extern kern_return_t get_thread_waitresult(thread_t); ! 661: ! 662: #endif /* _KERN_THREAD_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.