The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sys/lwp.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 6b8e0dd99bc40a8ea7fecfe39d67f0d5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.