Print this page




   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright (c) 2015, Joyent, Inc.  All rights reserved.
  29  */
  30 
  31 #ifndef _SYS_THREAD_H
  32 #define _SYS_THREAD_H
  33 
  34 
  35 #include <sys/types.h>
  36 #include <sys/t_lock.h>
  37 #include <sys/klwp.h>
  38 #include <sys/time.h>
  39 #include <sys/signal.h>
  40 #include <sys/kcpc.h>
  41 #if defined(__GNUC__) && defined(_ASM_INLINES) && defined(_KERNEL)
  42 #include <asm/thread.h>
  43 #endif
  44 
  45 #ifdef  __cplusplus
  46 extern "C" {
  47 #endif
  48 
  49 /*
  50  * The thread object, its states, and the methods by which it


  55  * Values that t_state may assume. Note that t_state cannot have more
  56  * than one of these flags set at a time.
  57  */
  58 #define TS_FREE         0x00    /* Thread at loose ends */
  59 #define TS_SLEEP        0x01    /* Awaiting an event */
  60 #define TS_RUN          0x02    /* Runnable, but not yet on a processor */
  61 #define TS_ONPROC       0x04    /* Thread is being run on a processor */
  62 #define TS_ZOMB         0x08    /* Thread has died but hasn't been reaped */
  63 #define TS_STOPPED      0x10    /* Stopped, initial state */
  64 #define TS_WAIT         0x20    /* Waiting to become runnable */
  65 
  66 typedef struct ctxop {
  67         void    (*save_op)(void *);     /* function to invoke to save context */
  68         void    (*restore_op)(void *);  /* function to invoke to restore ctx */
  69         void    (*fork_op)(void *, void *);     /* invoke to fork context */
  70         void    (*lwp_create_op)(void *, void *);       /* lwp_create context */
  71         void    (*exit_op)(void *);     /* invoked during {thread,lwp}_exit() */
  72         void    (*free_op)(void *, int); /* function which frees the context */
  73         void    *arg;           /* argument to above functions, ctx pointer */
  74         struct ctxop *next;     /* next context ops */
  75         hrtime_t save_ts;               /* timestamp of last save */
  76         hrtime_t restore_ts;            /* timestamp of last restore */
  77 } ctxop_t;
  78 
  79 /*
  80  * The active file descriptor table.
  81  * Each member of a_fd[] not equalling -1 represents an active fd.
  82  * The structure is initialized on first use; all zeros means uninitialized.
  83  */
  84 typedef struct {
  85         kmutex_t a_fdlock;      /* protects a_fd and a_nfd */
  86         int     *a_fd;          /* pointer to list of fds */
  87         int     a_nfd;          /* number of entries in *a_fd */
  88         int     a_stale;        /* one of the active fds is being closed */
  89         int     a_buf[2];       /* buffer to which a_fd initially refers */
  90 } afd_t;
  91 
  92 /*
  93  * An lwpchan provides uniqueness when sleeping on user-level
  94  * synchronization primitives.  The lc_wchan member is used
  95  * for sleeping on kernel synchronization primitives.
  96  */


 355 
 356 /*
 357  * Thread flag (t_flag) definitions.
 358  *      These flags must be changed only for the current thread,
 359  *      and not during preemption code, since the code being
 360  *      preempted could be modifying the flags.
 361  *
 362  *      For the most part these flags do not need locking.
 363  *      The following flags will only be changed while the thread_lock is held,
 364  *      to give assurrance that they are consistent with t_state:
 365  *              T_WAKEABLE
 366  */
 367 #define T_INTR_THREAD   0x0001  /* thread is an interrupt thread */
 368 #define T_WAKEABLE      0x0002  /* thread is blocked, signals enabled */
 369 #define T_TOMASK        0x0004  /* use lwp_sigoldmask on return from signal */
 370 #define T_TALLOCSTK     0x0008  /* thread structure allocated from stk */
 371 #define T_FORKALL       0x0010  /* thread was cloned by forkall() */
 372 #define T_WOULDBLOCK    0x0020  /* for lockfs */
 373 #define T_DONTBLOCK     0x0040  /* for lockfs */
 374 #define T_DONTPEND      0x0080  /* for lockfs */
 375 #define T_SPLITSTK      0x0100  /* kernel stack is currently split */
 376 #define T_WAITCVSEM     0x0200  /* waiting for a lwp_cv or lwp_sema on sleepq */
 377 #define T_WATCHPT       0x0400  /* thread undergoing a watchpoint emulation */
 378 #define T_PANIC         0x0800  /* thread initiated a system panic */
 379 #define T_LWPREUSE      0x1000  /* stack and LWP can be reused */
 380 #define T_CAPTURING     0x2000  /* thread is in page capture logic */
 381 #define T_VFPARENT      0x4000  /* thread is vfork parent, must call vfwait */
 382 #define T_DONTDTRACE    0x8000  /* disable DTrace probes */
 383 
 384 /*
 385  * Flags in t_proc_flag.
 386  *      These flags must be modified only when holding the p_lock
 387  *      for the associated process.
 388  */
 389 #define TP_DAEMON       0x0001  /* this is an LWP_DAEMON lwp */
 390 #define TP_HOLDLWP      0x0002  /* hold thread's lwp */
 391 #define TP_TWAIT        0x0004  /* wait to be freed by lwp_wait() */
 392 #define TP_LWPEXIT      0x0008  /* lwp has exited */
 393 #define TP_PRSTOP       0x0010  /* thread is being stopped via /proc */
 394 #define TP_CHKPT        0x0020  /* thread is being stopped via CPR checkpoint */
 395 #define TP_EXITLWP      0x0040  /* terminate this lwp */


 584  *      cpu_lock > sleepq locks > run queue locks
 585  */
 586 void    thread_transition(kthread_t *); /* move to transition lock */
 587 void    thread_stop(kthread_t *);       /* move to stop lock */
 588 void    thread_lock(kthread_t *);       /* lock thread and its queue */
 589 void    thread_lock_high(kthread_t *);  /* lock thread and its queue */
 590 void    thread_onproc(kthread_t *, struct cpu *); /* set onproc state lock */
 591 
 592 #define thread_unlock(t)                disp_lock_exit((t)->t_lockp)
 593 #define thread_unlock_high(t)           disp_lock_exit_high((t)->t_lockp)
 594 #define thread_unlock_nopreempt(t)      disp_lock_exit_nopreempt((t)->t_lockp)
 595 
 596 #define THREAD_LOCK_HELD(t)     (DISP_LOCK_HELD((t)->t_lockp))
 597 
 598 extern disp_lock_t transition_lock;     /* lock protecting transiting threads */
 599 extern disp_lock_t stop_lock;           /* lock protecting stopped threads */
 600 
 601 caddr_t thread_stk_init(caddr_t);       /* init thread stack */
 602 
 603 extern int default_binding_mode;
 604 extern int default_stksize;
 605 
 606 #endif  /* _KERNEL */
 607 
 608 /*
 609  * Macros to indicate that the thread holds resources that could be critical
 610  * to other kernel threads, so this thread needs to have kernel priority
 611  * if it blocks or is preempted.  Note that this is not necessary if the
 612  * resource is a mutex or a writer lock because of priority inheritance.
 613  *
 614  * The only way one thread may legally manipulate another thread's t_kpri_req
 615  * is to hold the target thread's thread lock while that thread is asleep.
 616  * (The rwlock code does this to implement direct handoff to waiting readers.)
 617  */
 618 #define THREAD_KPRI_REQUEST()   (curthread->t_kpri_req++)
 619 #define THREAD_KPRI_RELEASE()   (curthread->t_kpri_req--)
 620 #define THREAD_KPRI_RELEASE_N(n) (curthread->t_kpri_req -= (n))
 621 
 622 /*
 623  * Macro to change a thread's priority.
 624  */




   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 




  27 #ifndef _SYS_THREAD_H
  28 #define _SYS_THREAD_H
  29 
  30 
  31 #include <sys/types.h>
  32 #include <sys/t_lock.h>
  33 #include <sys/klwp.h>
  34 #include <sys/time.h>
  35 #include <sys/signal.h>
  36 #include <sys/kcpc.h>
  37 #if defined(__GNUC__) && defined(_ASM_INLINES) && defined(_KERNEL)
  38 #include <asm/thread.h>
  39 #endif
  40 
  41 #ifdef  __cplusplus
  42 extern "C" {
  43 #endif
  44 
  45 /*
  46  * The thread object, its states, and the methods by which it


  51  * Values that t_state may assume. Note that t_state cannot have more
  52  * than one of these flags set at a time.
  53  */
  54 #define TS_FREE         0x00    /* Thread at loose ends */
  55 #define TS_SLEEP        0x01    /* Awaiting an event */
  56 #define TS_RUN          0x02    /* Runnable, but not yet on a processor */
  57 #define TS_ONPROC       0x04    /* Thread is being run on a processor */
  58 #define TS_ZOMB         0x08    /* Thread has died but hasn't been reaped */
  59 #define TS_STOPPED      0x10    /* Stopped, initial state */
  60 #define TS_WAIT         0x20    /* Waiting to become runnable */
  61 
  62 typedef struct ctxop {
  63         void    (*save_op)(void *);     /* function to invoke to save context */
  64         void    (*restore_op)(void *);  /* function to invoke to restore ctx */
  65         void    (*fork_op)(void *, void *);     /* invoke to fork context */
  66         void    (*lwp_create_op)(void *, void *);       /* lwp_create context */
  67         void    (*exit_op)(void *);     /* invoked during {thread,lwp}_exit() */
  68         void    (*free_op)(void *, int); /* function which frees the context */
  69         void    *arg;           /* argument to above functions, ctx pointer */
  70         struct ctxop *next;     /* next context ops */


  71 } ctxop_t;
  72 
  73 /*
  74  * The active file descriptor table.
  75  * Each member of a_fd[] not equalling -1 represents an active fd.
  76  * The structure is initialized on first use; all zeros means uninitialized.
  77  */
  78 typedef struct {
  79         kmutex_t a_fdlock;      /* protects a_fd and a_nfd */
  80         int     *a_fd;          /* pointer to list of fds */
  81         int     a_nfd;          /* number of entries in *a_fd */
  82         int     a_stale;        /* one of the active fds is being closed */
  83         int     a_buf[2];       /* buffer to which a_fd initially refers */
  84 } afd_t;
  85 
  86 /*
  87  * An lwpchan provides uniqueness when sleeping on user-level
  88  * synchronization primitives.  The lc_wchan member is used
  89  * for sleeping on kernel synchronization primitives.
  90  */


 349 
 350 /*
 351  * Thread flag (t_flag) definitions.
 352  *      These flags must be changed only for the current thread,
 353  *      and not during preemption code, since the code being
 354  *      preempted could be modifying the flags.
 355  *
 356  *      For the most part these flags do not need locking.
 357  *      The following flags will only be changed while the thread_lock is held,
 358  *      to give assurrance that they are consistent with t_state:
 359  *              T_WAKEABLE
 360  */
 361 #define T_INTR_THREAD   0x0001  /* thread is an interrupt thread */
 362 #define T_WAKEABLE      0x0002  /* thread is blocked, signals enabled */
 363 #define T_TOMASK        0x0004  /* use lwp_sigoldmask on return from signal */
 364 #define T_TALLOCSTK     0x0008  /* thread structure allocated from stk */
 365 #define T_FORKALL       0x0010  /* thread was cloned by forkall() */
 366 #define T_WOULDBLOCK    0x0020  /* for lockfs */
 367 #define T_DONTBLOCK     0x0040  /* for lockfs */
 368 #define T_DONTPEND      0x0080  /* for lockfs */
 369 #define T_SYS_PROF      0x0100  /* profiling on for duration of system call */
 370 #define T_WAITCVSEM     0x0200  /* waiting for a lwp_cv or lwp_sema on sleepq */
 371 #define T_WATCHPT       0x0400  /* thread undergoing a watchpoint emulation */
 372 #define T_PANIC         0x0800  /* thread initiated a system panic */
 373 #define T_LWPREUSE      0x1000  /* stack and LWP can be reused */
 374 #define T_CAPTURING     0x2000  /* thread is in page capture logic */
 375 #define T_VFPARENT      0x4000  /* thread is vfork parent, must call vfwait */
 376 #define T_DONTDTRACE    0x8000  /* disable DTrace probes */
 377 
 378 /*
 379  * Flags in t_proc_flag.
 380  *      These flags must be modified only when holding the p_lock
 381  *      for the associated process.
 382  */
 383 #define TP_DAEMON       0x0001  /* this is an LWP_DAEMON lwp */
 384 #define TP_HOLDLWP      0x0002  /* hold thread's lwp */
 385 #define TP_TWAIT        0x0004  /* wait to be freed by lwp_wait() */
 386 #define TP_LWPEXIT      0x0008  /* lwp has exited */
 387 #define TP_PRSTOP       0x0010  /* thread is being stopped via /proc */
 388 #define TP_CHKPT        0x0020  /* thread is being stopped via CPR checkpoint */
 389 #define TP_EXITLWP      0x0040  /* terminate this lwp */


 578  *      cpu_lock > sleepq locks > run queue locks
 579  */
 580 void    thread_transition(kthread_t *); /* move to transition lock */
 581 void    thread_stop(kthread_t *);       /* move to stop lock */
 582 void    thread_lock(kthread_t *);       /* lock thread and its queue */
 583 void    thread_lock_high(kthread_t *);  /* lock thread and its queue */
 584 void    thread_onproc(kthread_t *, struct cpu *); /* set onproc state lock */
 585 
 586 #define thread_unlock(t)                disp_lock_exit((t)->t_lockp)
 587 #define thread_unlock_high(t)           disp_lock_exit_high((t)->t_lockp)
 588 #define thread_unlock_nopreempt(t)      disp_lock_exit_nopreempt((t)->t_lockp)
 589 
 590 #define THREAD_LOCK_HELD(t)     (DISP_LOCK_HELD((t)->t_lockp))
 591 
 592 extern disp_lock_t transition_lock;     /* lock protecting transiting threads */
 593 extern disp_lock_t stop_lock;           /* lock protecting stopped threads */
 594 
 595 caddr_t thread_stk_init(caddr_t);       /* init thread stack */
 596 
 597 extern int default_binding_mode;

 598 
 599 #endif  /* _KERNEL */
 600 
 601 /*
 602  * Macros to indicate that the thread holds resources that could be critical
 603  * to other kernel threads, so this thread needs to have kernel priority
 604  * if it blocks or is preempted.  Note that this is not necessary if the
 605  * resource is a mutex or a writer lock because of priority inheritance.
 606  *
 607  * The only way one thread may legally manipulate another thread's t_kpri_req
 608  * is to hold the target thread's thread lock while that thread is asleep.
 609  * (The rwlock code does this to implement direct handoff to waiting readers.)
 610  */
 611 #define THREAD_KPRI_REQUEST()   (curthread->t_kpri_req++)
 612 #define THREAD_KPRI_RELEASE()   (curthread->t_kpri_req--)
 613 #define THREAD_KPRI_RELEASE_N(n) (curthread->t_kpri_req -= (n))
 614 
 615 /*
 616  * Macro to change a thread's priority.
 617  */