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
328 #define t_dtrace_on _tdu._tds._t_dtrace_on
329 #define t_dtrace_step _tdu._tds._t_dtrace_step
330 #define t_dtrace_ret _tdu._tds._t_dtrace_ret
331 #define t_dtrace_ast _tdu._tds._t_dtrace_ast
332 #ifdef __amd64
333 #define t_dtrace_reg _tdu._tds._t_dtrace_reg
334 #endif
335
336 uintptr_t t_dtrace_pc; /* DTrace saved pc from fasttrap */
337 uintptr_t t_dtrace_npc; /* DTrace next pc from fasttrap */
338 uintptr_t t_dtrace_scrpc; /* DTrace per-thread scratch location */
339 uintptr_t t_dtrace_astpc; /* DTrace return sequence location */
340 #ifdef __amd64
341 uint64_t t_dtrace_regv; /* DTrace saved reg from fasttrap */
342 uint64_t t_useracc; /* SMAP state saved across swtch() */
343 #endif
344 hrtime_t t_hrtime; /* high-res last time on cpu */
345 kmutex_t t_ctx_lock; /* protects t_ctx in removectx() */
346 struct waitq *t_waitq; /* wait queue */
347 kmutex_t t_wait_mutex; /* used in CV wait functions */
348 } kthread_t;
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 */
572 * The locking heirarchy is as follows:
573 * cpu_lock > sleepq locks > run queue locks
574 */
575 void thread_transition(kthread_t *); /* move to transition lock */
576 void thread_stop(kthread_t *); /* move to stop lock */
577 void thread_lock(kthread_t *); /* lock thread and its queue */
578 void thread_lock_high(kthread_t *); /* lock thread and its queue */
579 void thread_onproc(kthread_t *, struct cpu *); /* set onproc state lock */
580
581 #define thread_unlock(t) disp_lock_exit((t)->t_lockp)
582 #define thread_unlock_high(t) disp_lock_exit_high((t)->t_lockp)
583 #define thread_unlock_nopreempt(t) disp_lock_exit_nopreempt((t)->t_lockp)
584
585 #define THREAD_LOCK_HELD(t) (DISP_LOCK_HELD((t)->t_lockp))
586
587 extern disp_lock_t transition_lock; /* lock protecting transiting threads */
588 extern disp_lock_t stop_lock; /* lock protecting stopped threads */
589
590 caddr_t thread_stk_init(caddr_t); /* init thread stack */
591
592 extern int default_binding_mode;
593
594 #endif /* _KERNEL */
595
596 /*
597 * Macros to indicate that the thread holds resources that could be critical
598 * to other kernel threads, so this thread needs to have kernel priority
599 * if it blocks or is preempted. Note that this is not necessary if the
600 * resource is a mutex or a writer lock because of priority inheritance.
601 *
602 * The only way one thread may legally manipulate another thread's t_kpri_req
603 * is to hold the target thread's thread lock while that thread is asleep.
604 * (The rwlock code does this to implement direct handoff to waiting readers.)
605 */
606 #define THREAD_KPRI_REQUEST() (curthread->t_kpri_req++)
607 #define THREAD_KPRI_RELEASE() (curthread->t_kpri_req--)
608 #define THREAD_KPRI_RELEASE_N(n) (curthread->t_kpri_req -= (n))
609
610 /*
611 * Macro to change a thread's priority.
612 */
613 #define THREAD_CHANGE_PRI(t, pri) { \
614 pri_t __new_pri = (pri); \
615 DTRACE_SCHED2(change__pri, kthread_t *, (t), pri_t, __new_pri); \
|
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 2018 Joyent, Inc.
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
332 #define t_dtrace_on _tdu._tds._t_dtrace_on
333 #define t_dtrace_step _tdu._tds._t_dtrace_step
334 #define t_dtrace_ret _tdu._tds._t_dtrace_ret
335 #define t_dtrace_ast _tdu._tds._t_dtrace_ast
336 #ifdef __amd64
337 #define t_dtrace_reg _tdu._tds._t_dtrace_reg
338 #endif
339
340 uintptr_t t_dtrace_pc; /* DTrace saved pc from fasttrap */
341 uintptr_t t_dtrace_npc; /* DTrace next pc from fasttrap */
342 uintptr_t t_dtrace_scrpc; /* DTrace per-thread scratch location */
343 uintptr_t t_dtrace_astpc; /* DTrace return sequence location */
344 #ifdef __amd64
345 uint64_t t_dtrace_regv; /* DTrace saved reg from fasttrap */
346 uint64_t t_useracc; /* SMAP state saved across swtch() */
347 #endif
348 hrtime_t t_hrtime; /* high-res last time on cpu */
349 kmutex_t t_ctx_lock; /* protects t_ctx in removectx() */
350 struct waitq *t_waitq; /* wait queue */
351 kmutex_t t_wait_mutex; /* used in CV wait functions */
352
353 char *t_name; /* thread name */
354 } kthread_t;
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 */
578 * The locking heirarchy is as follows:
579 * cpu_lock > sleepq locks > run queue locks
580 */
581 void thread_transition(kthread_t *); /* move to transition lock */
582 void thread_stop(kthread_t *); /* move to stop lock */
583 void thread_lock(kthread_t *); /* lock thread and its queue */
584 void thread_lock_high(kthread_t *); /* lock thread and its queue */
585 void thread_onproc(kthread_t *, struct cpu *); /* set onproc state lock */
586
587 #define thread_unlock(t) disp_lock_exit((t)->t_lockp)
588 #define thread_unlock_high(t) disp_lock_exit_high((t)->t_lockp)
589 #define thread_unlock_nopreempt(t) disp_lock_exit_nopreempt((t)->t_lockp)
590
591 #define THREAD_LOCK_HELD(t) (DISP_LOCK_HELD((t)->t_lockp))
592
593 extern disp_lock_t transition_lock; /* lock protecting transiting threads */
594 extern disp_lock_t stop_lock; /* lock protecting stopped threads */
595
596 caddr_t thread_stk_init(caddr_t); /* init thread stack */
597
598 int thread_setname(kthread_t *, const char *);
599 int thread_vsetname(kthread_t *, const char *, ...);
600
601 extern int default_binding_mode;
602
603 #endif /* _KERNEL */
604
605 #define THREAD_NAME_MAX 32 /* includes terminating NUL */
606
607 /*
608 * Macros to indicate that the thread holds resources that could be critical
609 * to other kernel threads, so this thread needs to have kernel priority
610 * if it blocks or is preempted. Note that this is not necessary if the
611 * resource is a mutex or a writer lock because of priority inheritance.
612 *
613 * The only way one thread may legally manipulate another thread's t_kpri_req
614 * is to hold the target thread's thread lock while that thread is asleep.
615 * (The rwlock code does this to implement direct handoff to waiting readers.)
616 */
617 #define THREAD_KPRI_REQUEST() (curthread->t_kpri_req++)
618 #define THREAD_KPRI_RELEASE() (curthread->t_kpri_req--)
619 #define THREAD_KPRI_RELEASE_N(n) (curthread->t_kpri_req -= (n))
620
621 /*
622 * Macro to change a thread's priority.
623 */
624 #define THREAD_CHANGE_PRI(t, pri) { \
625 pri_t __new_pri = (pri); \
626 DTRACE_SCHED2(change__pri, kthread_t *, (t), pri_t, __new_pri); \
|