Annotation of XNU/osfmk/kern/thread.h, revision 1.1.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.