Annotation of XNU/osfmk/kern/thread.h, revision 1.1

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_ */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.