diff options
Diffstat (limited to 'usr/src/uts/common/os/sig.c')
| -rw-r--r-- | usr/src/uts/common/os/sig.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/usr/src/uts/common/os/sig.c b/usr/src/uts/common/os/sig.c index 454b9e600f..481d6575af 100644 --- a/usr/src/uts/common/os/sig.c +++ b/usr/src/uts/common/os/sig.c @@ -56,6 +56,7 @@ #include <sys/core.h> #include <sys/schedctl.h> #include <sys/contract/process_impl.h> +#include <sys/cyclic.h> #include <sys/dtrace.h> #include <sys/sdt.h> @@ -2550,6 +2551,51 @@ trapsig(k_siginfo_t *ip, int restartable) mutex_exit(&p->p_lock); } +/* + * Arrange for the real time profiling signal to be dispatched. + */ +void +realsigprof(int sysnum, int nsysarg, int error) +{ + proc_t *p; + klwp_t *lwp; + + if (curthread->t_rprof->rp_anystate == 0) + return; + p = ttoproc(curthread); + lwp = ttolwp(curthread); + mutex_enter(&p->p_lock); + if (p->p_rprof_cyclic == CYCLIC_NONE) { + bzero(curthread->t_rprof, sizeof (*curthread->t_rprof)); + mutex_exit(&p->p_lock); + return; + } + if (sigismember(&p->p_ignore, SIGPROF) || + signal_is_blocked(curthread, SIGPROF)) { + mutex_exit(&p->p_lock); + return; + } + lwp->lwp_siginfo.si_signo = SIGPROF; + lwp->lwp_siginfo.si_code = PROF_SIG; + lwp->lwp_siginfo.si_errno = error; + hrt2ts(gethrtime(), &lwp->lwp_siginfo.si_tstamp); + lwp->lwp_siginfo.si_syscall = sysnum; + lwp->lwp_siginfo.si_nsysarg = nsysarg; + lwp->lwp_siginfo.si_fault = lwp->lwp_lastfault; + lwp->lwp_siginfo.si_faddr = lwp->lwp_lastfaddr; + lwp->lwp_lastfault = 0; + lwp->lwp_lastfaddr = NULL; + sigtoproc(p, curthread, SIGPROF); + mutex_exit(&p->p_lock); + ASSERT(lwp->lwp_cursig == 0); + if (issig(FORREAL)) + psig(); + mutex_enter(&p->p_lock); + lwp->lwp_siginfo.si_signo = 0; + bzero(curthread->t_rprof, sizeof (*curthread->t_rprof)); + mutex_exit(&p->p_lock); +} + #ifdef _SYSCALL32_IMPL /* |
