gonzui


Format: Advanced Search

t2ex/bsd_source/t2ex/network/net/src_bsd/sys/lwp.hbare sourcepermlink (0.04 seconds)

Search this content:

    1: /*      $NetBSD: lwp.h,v 1.114.4.1 2009/02/06 01:54:09 snj Exp $     */
    2: 
    3: /*-
    4:  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
    5:  * All rights reserved.
    6:  *
    7:  * This code is derived from software contributed to The NetBSD Foundation
    8:  * by Nathan J. Williams and Andrew Doran.
    9:  *
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer.
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in the
   17:  *    documentation and/or other materials provided with the distribution.
   18:  *
   19:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29:  * POSSIBILITY OF SUCH DAMAGE.
   30:  */
   31: 
   32: #ifndef _SYS_LWP_H_
   33: #define _SYS_LWP_H_
   34: 
   35: #include <sys/time.h>
   36: #ifndef T2EX
   37: #include <sys/queue.h>
   38: #else
   39: #include <sys/_queue.h>
   40: #endif
   41: #include <sys/callout.h>
   42: #include <sys/mutex.h>
   43: #include <sys/condvar.h>
   44: #ifndef T2EX
   45: #include <sys/signalvar.h>
   46: #include <sys/sched.h>
   47: #endif
   48: #include <sys/specificdata.h>
   49: #include <sys/syncobj.h>
   50: #include <sys/resource.h>
   51: 
   52: #ifndef T2EX
   53: #if defined(_KERNEL)
   54: #include <machine/cpu.h>                /* curcpu() and cpu_info */
   55: #endif
   56: 
   57: #include <machine/proc.h>               /* Machine-dependent proc substruct. */
   58: #endif
   59: 
   60: #ifdef T2EX
   61: struct  lwp {
   62:         struct proc *l_proc;   /* Process with which we are associated. */
   63: 
   64:         kmutex_t * volatile l_mutex;   /* l: ptr to mutex on sched state */
   65:         int            l_stat;           /* l: overall LWP status */
   66: 
   67:         int            l_selflag;        /* S: select() flags */
   68:         SLIST_HEAD(,selinfo) l_selwait;        /* S: descriptors waited on */
   69:         struct selcpu  *l_selcpu;       /* !: associated per-CPU select data */
   70:         struct filedesc        *l_fd;         /* !: cached copy of proc::p_fd */
   71:         int            l_dupfd;  /* !: side return from cloning devs XXX */
   72: 
   73:         /* Synchronisation */
   74:         TAILQ_ENTRY(lwp) l_sleepchain; /* l: sleep queue */
   75:         wchan_t                l_wchan;      /* l: sleep address */
   76:         struct sleepq  *l_sleepq;       /* l: current sleep queue */
   77:         callout_t      l_timeout_ch;        /* !: callout for tsleep */
   78: 
   79:         int            is_waiting;
   80: 
   81: };
   82: #else
   83: /*
   84:  * Lightweight process.  Field markings and the corresponding locks: 
   85:  *
   86:  * a:   proclist_mutex
   87:  * c:   condition variable interlock, passed to cv_wait()
   88:  * l:   *l_mutex
   89:  * p:   l_proc->p_lock
   90:  * s:   spc_mutex, which may or may not be referenced by l_mutex
   91:  * S:   l_selcpu->sc_lock
   92:  * (:   unlocked, stable
   93:  * !:   unlocked, may only be reliably accessed by the LWP itself
   94:  * ?:   undecided
   95:  *
   96:  * Fields are clustered together by usage (to increase the likelyhood
   97:  * of cache hits) and by size (to reduce dead space in the structure).
   98:  */
   99: struct lockdebug;
  100: struct sadata_vp;
  101: struct sysent;
  102: 
  103: struct lwp {
  104:         /* Scheduling and overall state */
  105:         TAILQ_ENTRY(lwp) l_runq;       /* s: run queue */
  106:         union {
  107:                 void *        info;          /* s: scheduler-specific structure */
  108:                 u_int timeslice;      /* l: time-quantum for SCHED_M2 */
  109:         } l_sched;
  110:         struct cpu_info *volatile l_cpu;/* s: CPU we're on if LSONPROC */
  111:         kmutex_t * volatile l_mutex;   /* l: ptr to mutex on sched state */
  112:         int            l_ctxswtch;       /* l: performing a context switch */
  113:         struct user    *l_addr;   /* l: KVA of u-area (PROC ONLY) */
  114:         struct mdlwp   l_md;             /* l: machine-dependent fields. */
  115:         int            l_flag;           /* l: misc flag values */
  116:         int            l_stat;           /* l: overall LWP status */
  117:         struct bintime         l_rtime;       /* l: real time */
  118:         struct bintime l_stime;        /* l: start time (while ONPROC) */
  119:         u_int          l_swtime;       /* l: time swapped in or out */
  120:         u_int          l_holdcnt;      /* l: if non-zero, don't swap */
  121:         u_int          l_rticks;       /* l: Saved start time of run */
  122:         u_int          l_rticksum;     /* l: Sum of ticks spent running */
  123:         u_int          l_slpticks;     /* l: Saved start time of sleep */
  124:         u_int          l_slpticksum;   /* l: Sum of ticks spent sleeping */
  125:         int            l_biglocks;       /* l: biglock count before sleep */
  126:         int            l_class;  /* l: scheduling class */
  127:         int            l_kpriority;      /* !: has kernel priority boost */
  128:         pri_t          l_kpribase;     /* !: kernel priority base level */
  129:         pri_t          l_priority;     /* l: scheduler priority */
  130:         pri_t          l_inheritedprio;/* l: inherited priority */
  131:         SLIST_HEAD(, turnstile) l_pi_lenders; /* l: ts lending us priority */
  132:         uint64_t       l_ncsw;               /* l: total context switches */
  133:         uint64_t       l_nivcsw;     /* l: involuntary context switches */
  134:         u_int          l_cpticks;      /* (: Ticks of CPU time */
  135:         fixpt_t                l_pctcpu;     /* p: %cpu during l_swtime */
  136:         fixpt_t                l_estcpu;     /* l: cpu time for SCHED_4BSD */
  137:         psetid_t       l_psid;               /* l: assigned processor-set ID */
  138:         struct cpu_info *l_target_cpu; /* l: target CPU to migrate */
  139:         kmutex_t       l_swaplock;   /* l: lock to prevent swapping */
  140:         struct lwpctl  *l_lwpctl;       /* p: lwpctl block kernel address */
  141:         struct lcpage  *l_lcpage;       /* p: lwpctl containing page */
  142:         kcpuset_t      *l_affinity; /* l: CPU set for affinity */
  143:         struct sadata_vp *l_savp;      /* p: SA "virtual processor" */
  144: 
  145:         /* Synchronisation */
  146:         struct turnstile *l_ts;                /* l: current turnstile */
  147:         struct syncobj *l_syncobj;     /* l: sync object operations set */
  148:         TAILQ_ENTRY(lwp) l_sleepchain; /* l: sleep queue */
  149:         wchan_t                l_wchan;      /* l: sleep address */
  150:         const char     *l_wmesg;   /* l: reason for sleep */
  151:         struct sleepq  *l_sleepq;       /* l: current sleep queue */
  152:         int            l_sleeperr;       /* !: error before unblock */
  153:         u_int          l_slptime;      /* l: time since last blocked */
  154:         callout_t      l_timeout_ch;        /* !: callout for tsleep */
  155: 
  156:         /* Process level and global state, misc. */
  157:         LIST_ENTRY(lwp)        l_list;                /* a: entry on list of all LWPs */
  158:         void           *l_ctxlink;      /* p: uc_link {get,set}context */
  159:         struct proc    *l_proc;   /* p: parent process */
  160:         LIST_ENTRY(lwp)        l_sibling;     /* p: entry on proc's list of LWPs */
  161:         lwpid_t                l_waiter;     /* p: first LWP waiting on us */
  162:         lwpid_t        l_waitingfor; /* p: specific LWP we are waiting on */
  163:         int            l_prflag; /* p: process level flags */
  164:         u_int          l_refcnt;       /* p: reference count on this LWP */
  165:         lwpid_t                l_lid;                /* (: LWP identifier; local to proc */
  166:         int            l_selflag;        /* S: select() flags */
  167:         SLIST_HEAD(,selinfo) l_selwait;        /* S: descriptors waited on */
  168:         struct selcpu  *l_selcpu;       /* !: associated per-CPU select data */
  169:         char           *l_name; /* (: name, optional */
  170: 
  171:         /* Signals */
  172:         int            l_sigrestore;     /* p: need to restore old sig mask */
  173:         sigset_t       l_sigwaitset; /* p: signals being waited for */
  174:         kcondvar_t     l_sigcv;    /* p: for sigsuspend() */
  175:         struct ksiginfo        *l_sigwaited;  /* p: delivered signals from set */
  176:         sigpend_t      *l_sigpendset;       /* p: XXX issignal()/postsig() baton */
  177:         LIST_ENTRY(lwp)        l_sigwaiter;   /* p: chain on list of waiting LWPs */
  178:         stack_t                l_sigstk;     /* p: sp & on stack state variable */
  179:         sigset_t       l_sigmask;    /* p: signal mask */
  180:         sigpend_t      l_sigpend;   /* p: signals to this LWP */
  181:         sigset_t       l_sigoldmask; /* p: mask for sigpause */
  182: 
  183:         /* Private data */
  184:         specificdata_reference
  185:                 l_specdataref;                /* !: subsystem lwp-specific data */
  186:         union {
  187:                 struct timeval tv;
  188:                 struct timespec ts;
  189:         } l_ktrcsw;                    /* !: for ktrace CSW trace XXX */
  190:         void           *l_private;      /* !: svr4-style lwp-private data */
  191:         struct lwp     *l_switchto;        /* !: mi_switch: switch to this LWP */
  192:         struct kauth_cred *l_cred;     /* !: cached credentials */
  193:         struct filedesc        *l_fd;         /* !: cached copy of proc::p_fd */
  194:         void           *l_emuldata;     /* !: kernel lwp-private data */
  195:         u_int          l_cv_signalled; /* c: restarted by cv_signal() */
  196:         u_short                l_shlocks;    /* !: lockdebug: shared locks held */
  197:         u_short                l_exlocks;    /* !: lockdebug: excl. locks held */
  198:         u_short                l_unused;     /* !: unused */
  199:         u_short                l_blcnt;      /* !: count of kernel_lock held */
  200:         int            l_nopreempt;      /* !: don't preempt me! */
  201:         u_int          l_dopreempt;    /* s: kernel preemption pending */
  202:         int            l_pflag;  /* !: LWP private flags */
  203:         int            l_dupfd;  /* !: side return from cloning devs XXX */
  204:         const struct sysent * volatile l_sysent;/* !: currently active syscall */
  205:         struct rusage  l_ru;            /* !: accounting information */
  206:         uint64_t       l_pfailtime;  /* !: for kernel preemption */
  207:         uintptr_t      l_pfailaddr; /* !: for kernel preemption */
  208:         uintptr_t      l_pfaillock; /* !: for kernel preemption */
  209:         _TAILQ_HEAD(,struct lockdebug,volatile) l_ld_locks;/* !: locks held by LWP */
  210: 
  211:         /* These are only used by 'options SYSCALL_TIMES' */
  212:         uint32_t        l_syscall_time; /* !: time epoch for current syscall */
  213:         uint64_t        *l_syscall_counter; /* !: counter for current process */
  214: };
  215: 
  216: #if !defined(USER_TO_UAREA)
  217: #if !defined(UAREA_USER_OFFSET)
  218: #define UAREA_USER_OFFSET       0
  219: #endif /* !defined(UAREA_USER_OFFSET) */
  220: #define USER_TO_UAREA(user)     ((vaddr_t)(user) - UAREA_USER_OFFSET)
  221: #define UAREA_TO_USER(uarea)    ((struct user *)((uarea) + UAREA_USER_OFFSET))
  222: #endif /* !defined(UAREA_TO_USER) */
  223: 
  224: LIST_HEAD(lwplist, lwp);                /* a list of LWPs */
  225: #endif
  226: 
  227: #ifdef _KERNEL
  228: #ifndef T2EX
  229: extern kmutex_t alllwp_mutex;           /* Mutex on alllwp */
  230: extern struct lwplist alllwp;           /* List of all LWPs. */
  231: 
  232: extern struct pool lwp_uc_pool;         /* memory pool for LWP startup args */
  233: #endif
  234: extern lwp_t lwp0;                      /* LWP for proc0 */
  235: #endif
  236: 
  237: /* These flags are kept in l_flag. */
  238: #define LW_IDLE         0x00000001 /* Idle lwp. */
  239: #define LW_INMEM        0x00000004 /* Loaded into memory. */
  240: #define LW_SINTR        0x00000080 /* Sleep is interruptible. */
  241: #define LW_SA_SWITCHING 0x00000100 /* SA LWP in context switch */
  242: #define LW_SYSTEM       0x00000200 /* Kernel thread */
  243: #define LW_SA           0x00000400 /* Scheduler activations LWP */
  244: #define LW_WSUSPEND     0x00020000 /* Suspend before return to user */
  245: #define LW_BATCH        0x00040000 /* LWP tends to hog CPU */
  246: #define LW_WCORE        0x00080000 /* Stop for core dump on return to user */
  247: #define LW_WEXIT        0x00100000 /* Exit before return to user */
  248: #define LW_AFFINITY     0x00200000 /* Affinity is assigned to the thread */
  249: #define LW_SA_UPCALL    0x00400000 /* SA upcall is pending */
  250: #define LW_SA_BLOCKING  0x00800000 /* Blocking in tsleep() */
  251: #define LW_PENDSIG      0x01000000 /* Pending signal for us */
  252: #define LW_CANCELLED    0x02000000 /* tsleep should not sleep */
  253: #define LW_WUSERRET     0x04000000 /* Call proc::p_userret on return to user */
  254: #define LW_WREBOOT      0x08000000 /* System is rebooting, please suspend */
  255: #define LW_UNPARKED     0x10000000 /* Unpark op pending */
  256: #define LW_SA_YIELD     0x40000000 /* LWP on VP is yielding */
  257: #define LW_SA_IDLE      0x80000000 /* VP is idle */
  258: 
  259: /* The second set of flags is kept in l_pflag. */
  260: #define LP_KTRACTIVE    0x00000001 /* Executing ktrace operation */
  261: #define LP_KTRCSW       0x00000002 /* ktrace context switch marker */
  262: #define LP_KTRCSWUSER   0x00000004 /* ktrace context switch marker */
  263: #define LP_OWEUPC       0x00000010 /* Owe user profiling tick */
  264: #define LP_MPSAFE       0x00000020 /* Starts life without kernel_lock */
  265: #define LP_INTR         0x00000040 /* Soft interrupt handler */
  266: #define LP_SYSCTLWRITE  0x00000080 /* sysctl write lock held */
  267: #define LP_SA_PAGEFAULT 0x00000200 /* SA LWP in pagefault handler */
  268: #define LP_SA_NOBLOCK   0x00000400 /* SA don't upcall on block */
  269: #define LP_TIMEINTR     0x00010000 /* Time this soft interrupt */
  270: #define LP_RUNNING      0x20000000 /* Active on a CPU */
  271: #define LP_BOUND        0x80000000 /* Bound to a CPU */
  272: 
  273: #ifndef T2EX
  274: /* The third set is kept in l_prflag. */
  275: #define LPR_DETACHED    0x00800000 /* Won't be waited for. */
  276: #define LPR_CRMOD       0x00000100 /* Credentials modified */
  277: 
  278: /*
  279:  * Mask indicating that there is "exceptional" work to be done on return to
  280:  * user.
  281:  */
  282: #define LW_USERRET (LW_WEXIT|LW_PENDSIG|LW_WREBOOT|LW_WSUSPEND|LW_WCORE|\
  283:                     LW_WUSERRET|LW_SA_BLOCKING|LW_SA_UPCALL)
  284: #endif
  285: 
  286: /*
  287:  * Status values.
  288:  *
  289:  * A note about SRUN and SONPROC: SRUN indicates that a process is
  290:  * runnable but *not* yet running, i.e. is on a run queue.  SONPROC
  291:  * indicates that the process is actually executing on a CPU, i.e.
  292:  * it is no longer on a run queue.
  293:  */
  294: #define LSIDL           1        /* Process being created by fork. */
  295: #define LSRUN           2        /* Currently runnable. */
  296: #define LSSLEEP         3      /* Sleeping on an address. */
  297: #define LSSTOP          4       /* Process debugging or suspension. */
  298: #define LSZOMB          5       /* Awaiting collection by parent. */
  299: /* unused, for source compatibility with NetBSD 4.0 and earlier. */
  300: #define LSDEAD          6       /* Process is almost a zombie. */
  301: #define LSONPROC        7      /* Process is currently on a CPU. */
  302: #define LSSUSPENDED     8   /* Not running, not signalable. */
  303: 
  304: #ifdef _KERNEL
  305: #ifndef T2EX
  306: #define LWP_CACHE_CREDS(l, p)                                           \
  307: do {                                                                    \
  308:         (void)p;                                                       \
  309:         if (__predict_false((l)->l_prflag & LPR_CRMOD))                        \
  310:                 lwp_update_creds(l);                                  \
  311: } while (/* CONSTCOND */ 0)
  312: 
  313: void    lwp_startup(lwp_t *, lwp_t *);
  314: 
  315: int     lwp_locked(lwp_t *, kmutex_t *);
  316: void    lwp_setlock(lwp_t *, kmutex_t *);
  317: void    lwp_unlock_to(lwp_t *, kmutex_t *);
  318: #endif
  319: kmutex_t *lwp_lock_retry(lwp_t *, kmutex_t *);
  320: #ifndef T2EX
  321: void    lwp_relock(lwp_t *, kmutex_t *);
  322: int     lwp_trylock(lwp_t *);
  323: void    lwp_addref(lwp_t *);
  324: void    lwp_delref(lwp_t *);
  325: void    lwp_drainrefs(lwp_t *);
  326: bool    lwp_alive(lwp_t *);
  327: lwp_t   *lwp_find_first(proc_t *);
  328: 
  329: /* Flags for _lwp_wait1 */
  330: #define LWPWAIT_EXITCONTROL     0x00000001
  331: void    lwpinit(void);
  332: int     lwp_wait1(lwp_t *, lwpid_t, lwpid_t *, int);
  333: void    lwp_continue(lwp_t *);
  334: void    cpu_setfunc(lwp_t *, void (*)(void *), void *);
  335: void    startlwp(void *);
  336: void    upcallret(lwp_t *);
  337: void    lwp_exit(lwp_t *) __dead;
  338: void    lwp_exit_switchaway(lwp_t *) __dead;
  339: int     lwp_suspend(lwp_t *, lwp_t *);
  340: int     lwp_create1(lwp_t *, const void *, size_t, u_long, lwpid_t *);
  341: void    lwp_update_creds(lwp_t *);
  342: void    lwp_migrate(lwp_t *, struct cpu_info *);
  343: lwp_t *lwp_find2(pid_t, lwpid_t);
  344: lwp_t *lwp_find(proc_t *, int);
  345: void    lwp_userret(lwp_t *);
  346: void    lwp_need_userret(lwp_t *);
  347: void    lwp_free(lwp_t *, bool, bool);
  348: void    lwp_sys_init(void);
  349: u_int   lwp_unsleep(lwp_t *, bool);
  350: 
  351: int     lwp_specific_key_create(specificdata_key_t *, specificdata_dtor_t);
  352: void    lwp_specific_key_delete(specificdata_key_t);
  353: void    lwp_initspecific(lwp_t *);
  354: void    lwp_finispecific(lwp_t *);
  355: void    *lwp_getspecific(specificdata_key_t);
  356: #if defined(_LWP_API_PRIVATE)
  357: void    *_lwp_getspecific_by_lwp(lwp_t *, specificdata_key_t);
  358: #endif
  359: void    lwp_setspecific(specificdata_key_t, void *);
  360: 
  361: /* Syscalls */
  362: int     lwp_park(struct timespec *, const void *);
  363: int     lwp_unpark(lwpid_t, const void *);
  364: 
  365: /* ddb */
  366: void lwp_whatis(uintptr_t, void (*)(const char *, ...));
  367: 
  368: #endif
  369: /*
  370:  * Lock an LWP. XXXLKM
  371:  */
  372: static inline void
  373: lwp_lock(lwp_t *l)
  374: {
  375:         kmutex_t *old;
  376: 
  377:         mutex_spin_enter(old = l->l_mutex);
  378: 
  379:         /*
  380:          * mutex_enter() will have posted a read barrier.  Re-test
  381:          * l->l_mutex.  If it has changed, we need to try again.
  382:          */
  383:         if (__predict_false(l->l_mutex != old))
  384:                 lwp_lock_retry(l, old);
  385: }
  386: 
  387: /*
  388:  * Unlock an LWP. XXXLKM
  389:  */
  390: static inline void
  391: lwp_unlock(lwp_t *l)
  392: {
  393:         mutex_spin_exit(l->l_mutex);
  394: }
  395: 
  396: #ifndef T2EX
  397: static inline void
  398: lwp_changepri(lwp_t *l, pri_t pri)
  399: {
  400:         KASSERT(mutex_owned(l->l_mutex));
  401: 
  402:         (*l->l_syncobj->sobj_changepri)(l, pri);
  403: }
  404: 
  405: static inline void
  406: lwp_lendpri(lwp_t *l, pri_t pri)
  407: {
  408:         KASSERT(mutex_owned(l->l_mutex));
  409: 
  410:         if (l->l_inheritedprio == pri)
  411:                 return;
  412: 
  413:         (*l->l_syncobj->sobj_lendpri)(l, pri);
  414: }
  415: 
  416: static inline pri_t
  417: lwp_eprio(lwp_t *l)
  418: {
  419:         pri_t pri;
  420: 
  421:         pri = l->l_priority;
  422:         if (l->l_kpriority && pri < PRI_KERNEL)
  423:                 pri = (pri >> 1) + l->l_kpribase;
  424:         return MAX(l->l_inheritedprio, pri);
  425: }
  426: 
  427: int lwp_create(lwp_t *, struct proc *, vaddr_t, bool, int,
  428:     void *, size_t, void (*)(void *), void *, lwp_t **, int);
  429: 
  430: /*
  431:  * We should provide real stubs for the below that LKMs can use.
  432:  */
  433: 
  434: static inline void
  435: spc_lock(struct cpu_info *ci)
  436: {
  437:         mutex_spin_enter(ci->ci_schedstate.spc_mutex);
  438: }
  439: 
  440: static inline void
  441: spc_unlock(struct cpu_info *ci)
  442: {
  443:         mutex_spin_exit(ci->ci_schedstate.spc_mutex);
  444: }
  445: 
  446: static inline void
  447: spc_dlock(struct cpu_info *ci1, struct cpu_info *ci2)
  448: {
  449:         struct schedstate_percpu *spc1 = &ci1->ci_schedstate;
  450:         struct schedstate_percpu *spc2 = &ci2->ci_schedstate;
  451: 
  452:         KASSERT(ci1 != ci2);
  453:         if (ci1 < ci2) {
  454:                 mutex_spin_enter(spc1->spc_mutex);
  455:                 mutex_spin_enter(spc2->spc_mutex);
  456:         } else {
  457:                 mutex_spin_enter(spc2->spc_mutex);
  458:                 mutex_spin_enter(spc1->spc_mutex);
  459:         }
  460: }
  461: #endif /* T2EX */
  462: #endif /* _KERNEL */
  463: 
  464: #ifdef _KERNEL
  465: /*
  466:  * Allow machine-dependent code to override curlwp in <machine/cpu.h> for
  467:  * its own convenience.  Otherwise, we declare it as appropriate.
  468:  */
  469: #if !defined(curlwp)
  470: #ifndef T2EX
  471: #if defined(MULTIPROCESSOR)
  472: #define curlwp          curcpu()->ci_curlwp     /* Current running LWP */
  473: #else
  474: extern struct lwp       *curlwp;              /* Current running LWP */
  475: #endif /* MULTIPROCESSOR */
  476: #else
  477: lwp_t* tkn_curlwp(void);
  478: #define curlwp  tkn_curlwp()
  479: #endif /* T2EX */
  480: #endif /* ! curlwp */
  481: #define curproc         (curlwp->l_proc)
  482: #endif
  483: 
  484: #ifndef T2EX
  485: #ifdef _KERNEL
  486: static inline bool
  487: CURCPU_IDLE_P(void)
  488: {
  489:         struct cpu_info *ci = curcpu();
  490:         return ci->ci_data.cpu_onproc == ci->ci_data.cpu_idlelwp;
  491: }
  492: 
  493: /*
  494:  * Disable and re-enable preemption.  Only for low-level kernel
  495:  * use.  Device drivers and anything that could potentially be
  496:  * compiled as a module should use kpreempt_disable() and
  497:  * kpreempt_enable().
  498:  */
  499: static inline void
  500: KPREEMPT_DISABLE(lwp_t *l)
  501: {
  502: 
  503:         KASSERT(l == curlwp);
  504:         l->l_nopreempt++;
  505:         __insn_barrier();
  506: }
  507: 
  508: static inline void
  509: KPREEMPT_ENABLE(lwp_t *l)
  510: {
  511: 
  512:         KASSERT(l == curlwp);
  513:         KASSERT(l->l_nopreempt > 0);
  514:         __insn_barrier();
  515:         if (--l->l_nopreempt != 0)
  516:                 return;
  517:         __insn_barrier();
  518:         if (__predict_false(l->l_dopreempt))
  519:                 kpreempt(0);
  520:         __insn_barrier();
  521: }
  522: 
  523: /* For lwp::l_dopreempt */
  524: #define DOPREEMPT_ACTIVE        0x01
  525: #define DOPREEMPT_COUNTED       0x02
  526: 
  527: #endif /* _KERNEL */
  528: 
  529: /* Flags for _lwp_create(), as per Solaris. */
  530: #define LWP_DETACHED    0x00000040
  531: #define LWP_SUSPENDED   0x00000080
  532: #define LWP_VFORK       0x80000000
  533: #endif
  534: 
  535: #endif  /* !_SYS_LWP_H_ */