diff options
author | 2013-10-08 03:50:06 +0000 | |
---|---|---|
committer | 2013-10-08 03:50:06 +0000 | |
commit | a554f8d9c26f17ff529f06b95d7012ef0acf0fc6 (patch) | |
tree | bef7ec274b156d91bea80729c0556b6621f8cfd1 /sys/kern/kern_clock.c | |
parent | If a thread sends a signal to its own process, then have that thread (diff) | |
download | wireguard-openbsd-a554f8d9c26f17ff529f06b95d7012ef0acf0fc6.tar.xz wireguard-openbsd-a554f8d9c26f17ff529f06b95d7012ef0acf0fc6.zip |
Fix delivery of SIGPROF and SIGVTALRM to threaded processes by having
hardclock() set a flag on the running thread and force AST processing,
and then have the thread signal itself from userret().
idea and flag names from FreeBSD
ok jsing@
Diffstat (limited to 'sys/kern/kern_clock.c')
-rw-r--r-- | sys/kern/kern_clock.c | 49 |
1 files changed, 12 insertions, 37 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 3d517b0c11b..3f1cdef2e6e 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clock.c,v 1.82 2013/08/13 05:52:23 guenther Exp $ */ +/* $OpenBSD: kern_clock.c,v 1.83 2013/10/08 03:50:07 guenther Exp $ */ /* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */ /*- @@ -144,40 +144,11 @@ initclocks(void) /* * hardclock does the accounting needed for ITIMER_PROF and ITIMER_VIRTUAL. * We don't want to send signals with psignal from hardclock because it makes - * MULTIPROCESSOR locking very complicated. Instead we use a small trick - * to send the signals safely and without blocking too many interrupts - * while doing that (signal handling can be heavy). - * - * hardclock detects that the itimer has expired, and schedules a timeout - * to deliver the signal. This works because of the following reasons: - * - The timeout can be scheduled with a 1 tick time because we're - * doing it before the timeout processing in hardclock. So it will - * be scheduled to run as soon as possible. - * - The timeout will be run in softclock which will run before we - * return to userland and process pending signals. - * - If the system is so busy that several VIRTUAL/PROF ticks are - * sent before softclock processing, we'll send only one signal. - * But if we'd send the signal from hardclock only one signal would - * be delivered to the user process. So userland will only see one - * signal anyway. + * MULTIPROCESSOR locking very complicated. Instead, to use an idea from + * FreeBSD, we set a flag on the thread and when it goes to return to + * userspace it signals itself. */ -void -virttimer_trampoline(void *v) -{ - struct process *pr = v; - - psignal(pr->ps_mainproc, SIGVTALRM); -} - -void -proftimer_trampoline(void *v) -{ - struct process *pr = v; - - psignal(pr->ps_mainproc, SIGPROF); -} - /* * The real-time timer, interrupting hz times per second. */ @@ -196,11 +167,15 @@ hardclock(struct clockframe *frame) */ if (CLKF_USERMODE(frame) && timerisset(&pr->ps_timer[ITIMER_VIRTUAL].it_value) && - itimerdecr(&pr->ps_timer[ITIMER_VIRTUAL], tick) == 0) - timeout_add(&pr->ps_virt_to, 1); + itimerdecr(&pr->ps_timer[ITIMER_VIRTUAL], tick) == 0) { + atomic_setbits_int(&p->p_flag, P_ALRMPEND); + need_proftick(p); + } if (timerisset(&pr->ps_timer[ITIMER_PROF].it_value) && - itimerdecr(&pr->ps_timer[ITIMER_PROF], tick) == 0) - timeout_add(&pr->ps_prof_to, 1); + itimerdecr(&pr->ps_timer[ITIMER_PROF], tick) == 0) { + atomic_setbits_int(&p->p_flag, P_PROFPEND); + need_proftick(p); + } } /* |