Annotation of XNU/osfmk/kern/thread_act.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:  * Copyright (c) 1993 The University of Utah and
        !            27:  * the Computer Systems Laboratory (CSL).  All rights reserved.
        !            28:  *
        !            29:  * Permission to use, copy, modify and distribute this software and its
        !            30:  * documentation is hereby granted, provided that both the copyright
        !            31:  * notice and this permission notice appear in all copies of the
        !            32:  * software, derivative works or modified versions, and any portions
        !            33:  * thereof, and that both notices appear in supporting documentation.
        !            34:  *
        !            35:  * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
        !            36:  * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
        !            37:  * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            38:  *
        !            39:  * CSL requests users of this software to return to [email protected] any
        !            40:  * improvements that they make and grant CSL redistribution rights.
        !            41:  *
        !            42:  *      Author: Bryan Ford, University of Utah CSL
        !            43:  *
        !            44:  *      File:   thread_act.h
        !            45:  *
        !            46:  *      thread activation definitions
        !            47:  */
        !            48: #ifndef        _KERN_THREAD_ACT_H_
        !            49: #define _KERN_THREAD_ACT_H_
        !            50: 
        !            51: #include <mach/mach_types.h>
        !            52: #include <mach/rpc.h>
        !            53: #include <mach/vm_param.h>
        !            54: #include <mach/thread_info.h>
        !            55: #include <mach/exception_types.h>
        !            56: 
        !            57: 
        !            58: #ifdef MACH_KERNEL_PRIVATE
        !            59: #include <mach_assert.h>
        !            60: #include <xkmachkernel.h>
        !            61: #include <thread_swapper.h>
        !            62: #include <cputypes.h>
        !            63: 
        !            64: #include <kern/lock.h>
        !            65: #include <kern/queue.h>
        !            66: #include <kern/etap_macros.h>
        !            67: #include <kern/thread.h>
        !            68: #include <kern/thread_pool.h>
        !            69: #include <ipc/ipc_port.h>
        !            70: #include <machine/thread_act.h>
        !            71: 
        !            72: /* Here is a description of the states an thread_activation may be in.
        !            73:  *
        !            74:  * An activation always has a valid task pointer, and it is always constant.
        !            75:  * The activation is only linked onto the task's activation list until
        !            76:  * the activation is terminated.
        !            77:  *
        !            78:  * An activation is in use or not, depending on whether its thread
        !            79:  * pointer is nonzero.  If it is not in use, it is just sitting idly
        !            80:  * waiting to be used by a thread.  The thread holds a reference on
        !            81:  * the activation while using it.
        !            82:  *
        !            83:  * An activation lives on an thread_pool if its pool_port pointer is nonzero.
        !            84:  * When in use, it can still live on an thread_pool, but it is not actually
        !            85:  * linked onto the thread_pool's list of available activations.  In this case,
        !            86:  * the act will return to its thread_pool as soon as it becomes unused.
        !            87:  *
        !            88:  * An activation is active until thread_terminate is called on it;
        !            89:  * then it is inactive, waiting for all references to be dropped.
        !            90:  * Future control operations on the terminated activation will fail,
        !            91:  * with the exception that act_yank still works if the activation is
        !            92:  * still on an RPC chain.  A terminated activation always has null
        !            93:  * thread and pool_port pointers.
        !            94:  *
        !            95:  * An activation is suspended when suspend_count > 0.
        !            96:  * A suspended activation can live on an thread_pool, but it is not
        !            97:  * actually linked onto the thread_pool while suspended.
        !            98:  *
        !            99:  * Locking note:  access to data relevant to scheduling state (user_stop_count,
        !           100:  * suspend_count, handlers, special_handler) is controlled by the combination
        !           101:  * of locks acquired by act_lock_thread().  That is, not only must act_lock()
        !           102:  * be held, but RPC through the activation must be frozen (so that the
        !           103:  * thread pointer doesn't change).  If a shuttle is associated with the
        !           104:  * activation, then its thread_lock() must also be acquired to change these
        !           105:  * data.  Regardless of whether a shuttle is present, the data must be
        !           106:  * altered at splsched().
        !           107:  */
        !           108: 
        !           109: typedef struct ReturnHandler {
        !           110:        struct ReturnHandler *next;
        !           111:        void (*handler)(struct ReturnHandler *rh,
        !           112:                                struct thread_activation *thr_act);
        !           113: } ReturnHandler;
        !           114: 
        !           115: typedef struct thread_activation {
        !           116: 
        !           117:        /*** task linkage ***/
        !           118: 
        !           119:        /* Links for task's circular list of activations.  The activation
        !           120:         * is only on the task's activation list while active.  Must be
        !           121:         * first.
        !           122:         */
        !           123:        queue_chain_t   thr_acts;
        !           124: 
        !           125:        /* Indicators for whether this activation is in the midst of
        !           126:         * resuming or has already been resumed in a kernel-loaded
        !           127:         * task -- these flags are basically for quick access to
        !           128:         * this information.
        !           129:         */
        !           130:        boolean_t       kernel_loaded;  /* running in kernel-loaded task */
        !           131:        boolean_t       kernel_loading; /* about to run kernel-loaded */
        !           132: 
        !           133:        /*** Machine-dependent state ***/
        !           134:        struct MachineThrAct    mact;
        !           135: 
        !           136:        /*** Consistency ***/
        !           137:        decl_mutex_data(,lock)
        !           138:        decl_simple_lock_data(,sched_lock)
        !           139:        int             ref_count;
        !           140: 
        !           141:        /* Reference to the task this activation is in.
        !           142:         * Constant for the life of the activation
        !           143:         */
        !           144:        struct task     *task;
        !           145:        vm_map_t        map;            /* cached current map */
        !           146: 
        !           147:        /*** thread_pool-related stuff ***/
        !           148:        /* Port containing the thread_pool this activation normally lives
        !           149:         * on, zero if none.  The port (really the thread_pool) holds a
        !           150:         * reference to the activation as long as this is nonzero (even when
        !           151:         * the activation isn't actually on the thread_pool's list).
        !           152:         */
        !           153:        struct ipc_port *pool_port;
        !           154: 
        !           155:        /* Link on the thread_pool's list of activations.
        !           156:         * The activation is only actually on the thread_pool's list
        !           157:         * (and hence this is valid) when not in use (thread == 0) and
        !           158:         * not suspended (suspend_count == 0).
        !           159:         */
        !           160:        struct thread_activation *thread_pool_next;
        !           161: 
        !           162:        /* User stack location and size for initialization on migrating RPCs */
        !           163:        vm_offset_t     user_stack;
        !           164:        vm_size_t       user_stack_size;
        !           165: 
        !           166:         /*
        !           167:          * Entry point for upcall w/o registered subsystem and pointer
        !           168:          * to return code
        !           169:          */
        !           170:         entry_function_t        user_entry;
        !           171: 
        !           172:        /* RPC state */
        !           173:         union {
        !           174:                 struct {
        !           175:                         rpc_subsystem_t         r_subsystem;
        !           176: #if 0 /* Grenoble */
        !           177:                         mach_rpc_id_t           r_routine_num;
        !           178:                         mach_rpc_signature_t    r_sig_ptr;
        !           179:                         mach_rpc_size_t         r_sig_size;
        !           180: #else
        !           181:                         rpc_id_t           r_routine_num;
        !           182:                         rpc_signature_t    r_sig_ptr;      /* Stored Client Sig Ptr */
        !           183:                         rpc_size_t         r_sig_size;     /* Size of Sig stored */
        !           184:                        struct rpc_signature r_sigbuf;     /* Static Reservation of Sig Mem */
        !           185:                        routine_descriptor_t    r_sigbufp;      /* For dynamic storage of Sig */
        !           186:                        vm_size_t               r_sigbuf_size;  /* Size of buffer allocated for sig */
        !           187: #endif
        !           188:                         vm_offset_t             r_new_argv;
        !           189:                         vm_offset_t            *r_arg_buf;
        !           190:                         vm_offset_t             r_arg_buf_data[RPC_KBUF_SIZE];
        !           191:                         rpc_copy_state_t        r_state;
        !           192:                         rpc_copy_state_data_t   r_state_data[RPC_DESC_COUNT];
        !           193:                         unsigned int            r_port_flags;
        !           194:                         ipc_port_t              r_local_port;
        !           195:                         void                   *r_kkt_args;
        !           196:                 } regular;
        !           197:                 struct {
        !           198:                         ipc_port_t              r_port;
        !           199:                         ipc_port_t              r_exc_port;
        !           200:                        int                     r_exc_flavor;
        !           201:                        mach_msg_type_number_t  r_ostate_cnt;
        !           202:                        exception_data_type_t   r_code[EXCEPTION_CODE_MAX];
        !           203: #if                     ETAP_EVENT_MONITOR
        !           204:                         exception_type_t        r_exception;
        !           205: #endif
        !           206:                 } exception;
        !           207:         } rpc_state;
        !           208: 
        !           209:        /*** Thread linkage ***/
        !           210:        /* Shuttle using this activation, zero if not in use.  The shuttle
        !           211:         * holds a reference on the activation while this is nonzero.
        !           212:         */
        !           213:        struct thread_shuttle   *thread;
        !           214: 
        !           215:        /* The rest in this section is only valid when thread is nonzero.  */
        !           216: 
        !           217:        /* Next higher and next lower activation on the thread's activation
        !           218:         * stack.  For a topmost activation or the null_act, higher is
        !           219:         * undefined.  The bottommost activation is always the null_act.
        !           220:         */
        !           221:        struct thread_activation *higher, *lower;
        !           222: 
        !           223:        /* Alert bits pending at this activation; some of them may have
        !           224:         * propagated from lower activations.
        !           225:         */
        !           226:        unsigned        alerts;
        !           227: 
        !           228:        /* Mask of alert bits to be allowed to pass through from lower levels.
        !           229:         */
        !           230:        unsigned        alert_mask;
        !           231: 
        !           232: #if 0 /* Grenoble */
        !           233:        /* Saved policy and priority of shuttle if changed to migrate into
        !           234:         * higher-priority or more real-time task.  Only valid if
        !           235:         * saved_sched_stamp is nonzero and equal to the sched_change_stamp
        !           236:         * in the thread_shuttle.  (Otherwise, the policy or priority has
        !           237:         * been explicitly changed in the meantime, and the saved values
        !           238:         * are invalid.)
        !           239:         */
        !           240:        policy_t        saved_policy;
        !           241:        integer_t       saved_base_priority;
        !           242:        unsigned int    saved_sched_change_stamp;
        !           243: #endif
        !           244:        /*** Control information ***/
        !           245: 
        !           246:        /* Number of outstanding suspensions on this activation.  */
        !           247:        int             suspend_count;
        !           248: 
        !           249:        /* User-visible scheduling state */
        !           250:        int             user_stop_count;        /* outstanding stops */
        !           251: 
        !           252:        /* ast is needed - see ast.h */
        !           253:        int             ast;
        !           254: 
        !           255: #if    THREAD_SWAPPER
        !           256:        /* task swapper */
        !           257:        int             swap_state;     /* swap state (or unswappable flag)*/
        !           258:        queue_chain_t   swap_queue;     /* links on swap queues */
        !           259: #if    MACH_ASSERT
        !           260:        boolean_t       kernel_stack_swapped_in;
        !           261:                                        /* debug for thread swapping */
        !           262: #if    THREAD_SWAP_UNWIRE_USER_STACK
        !           263:        boolean_t       user_stack_swapped_in;
        !           264:                                        /* debug for thread swapping */
        !           265: #endif /* THREAD_SWAP_UNWIRE_USER_STACK */
        !           266: #endif /* MACH_ASSERT */
        !           267: #endif /* THREAD_SWAPPER */
        !           268: 
        !           269:        /* This is normally true, but is set to false when the
        !           270:         * activation is terminated.
        !           271:         */
        !           272:        int             active;
        !           273: 
        !           274:        /* Chain of return handlers to be called before the thread is
        !           275:         * allowed to return to this invocation
        !           276:         */
        !           277:        ReturnHandler   *handlers;
        !           278: 
        !           279:        /* A special ReturnHandler attached to the above chain to
        !           280:         * handle suspension and such
        !           281:         */
        !           282:        ReturnHandler   special_handler;
        !           283: 
        !           284:        /* Special ports attached to this activation */
        !           285:        struct ipc_port *ith_self;      /* not a right, doesn't hold ref */
        !           286:        struct ipc_port *ith_sself;     /* a send right */
        !           287:        struct exception_action exc_actions[EXC_TYPES_COUNT];
        !           288: 
        !           289:        /* A list of ulocks (a lock set element) currently held by the thread
        !           290:         */
        !           291:        queue_head_t    held_ulocks;
        !           292: 
        !           293: #if    XKMACHKERNEL
        !           294:        void            *xk_resources;
        !           295: #endif /* XKMACHKERNEL */
        !           296: 
        !           297: #if    MACH_PROF
        !           298:        /* Profiling data structures */
        !           299:        boolean_t       act_profiled;   /* is activation being profiled? */
        !           300:        boolean_t       act_profiled_own;
        !           301:                                        /* is activation being profiled 
        !           302:                                         * on its own ? */
        !           303:        struct prof_data *profil_buffer;/* prof struct if either is so */
        !           304: #endif /* MACH_PROF */
        !           305: #ifdef  MACH_BSD
        !           306:   /*
        !           307:    * WARNING:  you must change this constant if the size of
        !           308:    * user.h:struct uthread changes
        !           309:    */
        !           310:        unsigned char   bsd_space[288];
        !           311: #endif
        !           312: 
        !           313: } Thread_Activation;
        !           314: 
        !           315: /* RPC state fields */
        !           316: #define r_subsystem     rpc_state.regular.r_subsystem
        !           317: #define r_routine_num   rpc_state.regular.r_routine_num
        !           318: #define r_sig_ptr       rpc_state.regular.r_sig_ptr
        !           319: #define r_sig_size      rpc_state.regular.r_sig_size
        !           320: #define r_sigbuf       rpc_state.regular.r_sigbuf
        !           321: #define r_sigbufp      rpc_state.regular.r_sigbufp
        !           322: #define r_sigbuf_size   rpc_state.regular.r_sigbuf_size
        !           323: #define r_new_argv      rpc_state.regular.r_new_argv
        !           324: #define r_arg_buf       rpc_state.regular.r_arg_buf
        !           325: #define r_arg_buf_data  rpc_state.regular.r_arg_buf_data
        !           326: #define r_state         rpc_state.regular.r_state
        !           327: #define r_state_data    rpc_state.regular.r_state_data
        !           328: #define r_port_flags    rpc_state.regular.r_port_flags
        !           329: #define r_local_port    rpc_state.regular.r_local_port
        !           330: #define r_kkt_args      rpc_state.regular.r_kkt_args
        !           331: #define r_port          rpc_state.exception.r_port
        !           332: #define r_exc_port      rpc_state.exception.r_exc_port
        !           333: #define r_exc_flavor   rpc_state.exception.r_exc_flavor
        !           334: #define r_ostate_cnt   rpc_state.exception.r_ostate_cnt
        !           335: #define r_code          rpc_state.exception.r_code
        !           336: #define r_exception     rpc_state.exception.r_exception
        !           337: 
        !           338: /* Alert bits */
        !           339: #define SERVER_TERMINATED              0x01
        !           340: #define ORPHANED                       0x02
        !           341: #define CLIENT_TERMINATED              0x04
        !           342: #define TIME_CONSTRAINT_UNSATISFIED    0x08
        !           343: 
        !           344: #if THREAD_SWAPPER
        !           345: /*
        !           346:  * Encapsulate the actions needed to ensure that next lower act on
        !           347:  * RPC chain is swapped in.  Used at base spl; assumes rpc_lock()
        !           348:  * of thread is held; if port is non-null, assumes its ip_lock()
        !           349:  * is also held.
        !           350:  */
        !           351: #define act_switch_swapcheck(thread, port)                     \
        !           352: MACRO_BEGIN                                                    \
        !           353:        thread_act_t __act__ = thread->top_act;                 \
        !           354:                                                                \
        !           355:        while (__act__->lower) {                                \
        !           356:                thread_act_t __l__ = __act__->lower;            \
        !           357:                                                                \
        !           358:                if (__l__->swap_state == TH_SW_IN ||            \
        !           359:                        __l__->swap_state == TH_SW_UNSWAPPABLE) \
        !           360:                        break;                                  \
        !           361:                /*                                              \
        !           362:                 * XXX - Do we need to reference __l__?         \
        !           363:                 */                                             \
        !           364:                if (port)                                       \
        !           365:                        ip_unlock(port);                        \
        !           366:                if (!thread_swapin_blocking(__l__))             \
        !           367:                        panic("act_switch_swapcheck: !active"); \
        !           368:                if (port)                                       \
        !           369:                        ip_lock(port);                          \
        !           370:                if (__act__->lower == __l__)                    \
        !           371:                        break;                                  \
        !           372:        }                                                       \
        !           373: MACRO_END
        !           374: 
        !           375: #else  /* !THREAD_SWAPPER */
        !           376: 
        !           377: #define act_switch_swapcheck(thread, port)
        !           378: 
        !           379: #endif /* !THREAD_SWAPPER */
        !           380: 
        !           381: #define        act_lock_init(thr_act)  mutex_init(&(thr_act)->lock, ETAP_THREAD_ACT)
        !           382: #define        act_lock(thr_act)       mutex_lock(&(thr_act)->lock)
        !           383: #define        act_lock_try(thr_act)   mutex_try(&(thr_act)->lock)
        !           384: #define        act_unlock(thr_act)     mutex_unlock(&(thr_act)->lock)
        !           385: 
        !           386: /* Sanity check the ref count.  If it is 0, we may be doubly zfreeing.
        !           387:  * If it is larger than max int, it has been corrupted, probably by being
        !           388:  * modified into an address (this is architecture dependent, but it's
        !           389:  * safe to assume there cannot really be max int references).
        !           390:  */
        !           391: #define ACT_MAX_REFERENCES                                     \
        !           392:        (unsigned)(~0 ^ (1 << (sizeof(int)*BYTE_SIZE - 1)))
        !           393: 
        !           394: #define                act_reference(thr_act)                          \
        !           395:                MACRO_BEGIN                                     \
        !           396:                    if (thr_act) {                              \
        !           397:                        act_lock(thr_act);                      \
        !           398:                        assert((thr_act)->ref_count < ACT_MAX_REFERENCES); \
        !           399:                        if ((thr_act)->ref_count <= 0) \
        !           400:                                panic("act_reference: already freed"); \
        !           401:                        (thr_act)->ref_count++;                 \
        !           402:                        act_unlock(thr_act);                    \
        !           403:                    }                                           \
        !           404:                MACRO_END
        !           405: 
        !           406: #define                act_locked_act_reference(thr_act)               \
        !           407:                MACRO_BEGIN                                     \
        !           408:                    if (thr_act) {                              \
        !           409:                        assert((thr_act)->ref_count < ACT_MAX_REFERENCES); \
        !           410:                        if ((thr_act)->ref_count <= 0) \
        !           411:                                panic("a_l_act_reference: already freed"); \
        !           412:                        (thr_act)->ref_count++;                 \
        !           413:                    }                                           \
        !           414:                MACRO_END
        !           415: 
        !           416: #define        sigbuf_dealloc(thr_act)                                 \
        !           417:                if ((thr_act->r_sigbufp) && (thr_act->r_sigbuf_size >   \
        !           418:                                         sizeof(thr_act->r_sigbuf)))    \
        !           419:                 {                                                      \
        !           420:                     KFREE((vm_offset_t)thr_act->r_sigbufp,             \
        !           421:                             thr_act->r_sigbuf_size,                    \
        !           422:                             thr_act->r_port_flags & IPC_PORT_FLAGS_RT); \
        !           423:                     thr_act->r_sigbuf_size = 0;                        \
        !           424:                 }                                              
        !           425: 
        !           426: #define                act_deallocate(thr_act)                         \
        !           427:                MACRO_BEGIN                                     \
        !           428:                    if (thr_act) {                              \
        !           429:                        int new_value;                          \
        !           430:                        act_lock(thr_act);                      \
        !           431:                        assert((thr_act)->ref_count > 0 &&      \
        !           432:                            (thr_act)->ref_count <= ACT_MAX_REFERENCES); \
        !           433:                        new_value = --(thr_act)->ref_count;     \
        !           434:                        if (new_value == 0) {                   \
        !           435:                            sigbuf_dealloc(thr_act);            \
        !           436:                            act_free(thr_act);                  \
        !           437:                        }                                       \
        !           438:                        else act_unlock(thr_act);               \
        !           439:                    }                                           \
        !           440:                MACRO_END
        !           441: 
        !           442: #define                act_locked_act_deallocate(thr_act)              \
        !           443:                MACRO_BEGIN                                     \
        !           444:                    if (thr_act) {                              \
        !           445:                        int new_value;                          \
        !           446:                        assert((thr_act)->ref_count > 0 &&      \
        !           447:                            (thr_act)->ref_count <= ACT_MAX_REFERENCES); \
        !           448:                        new_value = --(thr_act)->ref_count;     \
        !           449:                        if (new_value == 0) {                   \
        !           450:                            panic("a_l_act_deallocate: would free act"); \
        !           451:                        }                                       \
        !           452:                    }                                           \
        !           453:                MACRO_END
        !           454: 
        !           455: 
        !           456: extern void            act_init(void);
        !           457: extern kern_return_t   act_disable_task_locked(thread_act_t);
        !           458: extern void            thread_release(thread_act_t);
        !           459: extern kern_return_t   thread_dowait(thread_act_t, boolean_t);
        !           460: extern void            thread_hold(thread_act_t);
        !           461: extern void            nudge(thread_act_t);
        !           462: 
        !           463: extern kern_return_t   act_set_thread_pool(thread_act_t, ipc_port_t);
        !           464: extern kern_return_t   act_locked_act_set_thread_pool(thread_act_t, ipc_port_t);
        !           465: extern kern_return_t   thread_get_special_port(thread_act_t, int,
        !           466:                                        ipc_port_t *);
        !           467: extern kern_return_t   thread_set_special_port(thread_act_t, int,
        !           468:                                        ipc_port_t);
        !           469: extern thread_t                act_lock_thread(thread_act_t);
        !           470: extern void            act_unlock_thread(thread_act_t);
        !           471: extern void            install_special_handler(thread_act_t);
        !           472: extern thread_act_t    thread_lock_act(thread_t);
        !           473: extern void            thread_unlock_act(thread_t);
        !           474: extern void            act_attach(thread_act_t, thread_t, unsigned);
        !           475: extern void            act_execute_returnhandlers(void);
        !           476: extern void            act_detach(thread_act_t);
        !           477: extern void            act_free(thread_act_t);
        !           478: 
        !           479: /* machine-dependent functions */
        !           480: extern void            act_machine_return(kern_return_t);
        !           481: extern void            act_machine_init(void);
        !           482: extern kern_return_t   act_machine_create(struct task *, thread_act_t);
        !           483: extern void            act_machine_destroy(thread_act_t);
        !           484: extern kern_return_t   act_machine_set_state(thread_act_t,
        !           485:                                        thread_flavor_t, thread_state_t,
        !           486:                                        mach_msg_type_number_t );
        !           487: extern kern_return_t   act_machine_get_state(thread_act_t,
        !           488:                                        thread_flavor_t, thread_state_t,
        !           489:                                        mach_msg_type_number_t *);
        !           490: extern void            act_machine_switch_pcb(thread_act_t);
        !           491: 
        !           492: extern kern_return_t   act_create(task_t, thread_act_params_t params,
        !           493:                                   thread_act_t *);
        !           494: extern kern_return_t   act_get_state(thread_act_t, int, thread_state_t,
        !           495:                                mach_msg_type_number_t *);
        !           496: extern kern_return_t   act_set_state(thread_act_t, int, thread_state_t,
        !           497:                                mach_msg_type_number_t);
        !           498: 
        !           499: extern int             dump_act(thread_act_t); /* debugging */
        !           500: 
        !           501: #define current_act_fast()     (current_thread()->top_act)
        !           502: #define current_act_slow()     ((current_thread()) ?           \
        !           503:                                 current_act_fast() :           \
        !           504:                                 THR_ACT_NULL)
        !           505: 
        !           506: #define current_act() current_act_slow()    /* JMM - til we find the culprit */
        !           507: 
        !           508: #else /* !MACH_KERNEL_PRIVATE */
        !           509: 
        !           510: extern thread_act_t            current_act(void);
        !           511: 
        !           512: #endif /* !MACH_KERNEL_PRIVATE */
        !           513: 
        !           514: /* Exported to world */
        !           515: extern kern_return_t   act_alert(thread_act_t, unsigned);
        !           516: extern kern_return_t   act_alert_mask(thread_act_t, unsigned );
        !           517: extern kern_return_t   post_alert(thread_act_t, unsigned);
        !           518: 
        !           519: extern kern_return_t   thread_abort(thread_act_t);
        !           520: extern kern_return_t   thread_abort_safely(thread_act_t);
        !           521: extern kern_return_t   thread_resume(thread_act_t);
        !           522: extern kern_return_t   thread_suspend(thread_act_t);
        !           523: extern kern_return_t   thread_terminate(thread_act_t);
        !           524: 
        !           525: typedef void (thread_apc_handler_t)(thread_act_t);
        !           526: 
        !           527: extern kern_return_t   thread_apc_set(thread_act_t, thread_apc_handler_t);
        !           528: extern kern_return_t   thread_apc_clear(thread_act_t, thread_apc_handler_t);
        !           529: 
        !           530: extern void            set_act_map(thread_act_t, vm_map_t);
        !           531: 
        !           532: extern void            *get_bsdthread_info(thread_act_t);
        !           533: extern void            set_bsdthread_info(thread_act_t, void *);
        !           534: extern task_t          get_threadtask(thread_act_t);
        !           535: 
        !           536: #endif /* _KERN_THREAD_ACT_H_ */

unix.superglobalmegacorp.com

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