diff options
Diffstat (limited to 'usr/src/lib/libc/port/threads/sigaction.c')
-rw-r--r-- | usr/src/lib/libc/port/threads/sigaction.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/usr/src/lib/libc/port/threads/sigaction.c b/usr/src/lib/libc/port/threads/sigaction.c index 529530f2af..3d8f747100 100644 --- a/usr/src/lib/libc/port/threads/sigaction.c +++ b/usr/src/lib/libc/port/threads/sigaction.c @@ -83,6 +83,9 @@ call_user_handler(int sig, siginfo_t *sip, ucontext_t *ucp) * while holding the sig's sig_lock for the least possible time. * We must acquire the sig's sig_lock because some thread running * in sigaction() might be establishing a new signal handler. + * The code in sigaction() acquires the writer lock; here + * we acquire the readers lock to ehance concurrency in the + * face of heavy signal traffic, such as generated by java. * * Locking exceptions: * No locking for a child of vfork(). @@ -103,12 +106,12 @@ call_user_handler(int sig, siginfo_t *sip, ucontext_t *ucp) /* we wish this assignment could be atomic */ (void) _private_memcpy(&uact, (void *)sap, sizeof (uact)); } else { - mutex_t *mp = &udp->siguaction[sig].sig_lock; - lmutex_lock(mp); + rwlock_t *rwlp = &udp->siguaction[sig].sig_lock; + lrw_rdlock(rwlp); (void) _private_memcpy(&uact, (void *)sap, sizeof (uact)); if (sig == SIGCANCEL && (sap->sa_flags & SA_RESETHAND)) sap->sa_sigaction = SIG_DFL; - lmutex_unlock(mp); + lrw_unlock(rwlp); } /* @@ -324,7 +327,7 @@ _libc_sigaction(int sig, const struct sigaction *nact, struct sigaction *oact) } if (!self->ul_vfork) - lmutex_lock(&udp->siguaction[sig].sig_lock); + lrw_wrlock(&udp->siguaction[sig].sig_lock); oaction = udp->siguaction[sig].sig_uaction; @@ -401,7 +404,7 @@ _libc_sigaction(int sig, const struct sigaction *nact, struct sigaction *oact) } if (!self->ul_vfork) - lmutex_unlock(&udp->siguaction[sig].sig_lock); + lrw_unlock(&udp->siguaction[sig].sig_lock); return (rv); } @@ -633,7 +636,7 @@ _sigprocmask(int how, const sigset_t *set, sigset_t *oset) /* * Called at library initialization to set up signal handling. - * All we really do is initialize the sig_lock mutexes. + * All we really do is initialize the sig_lock rwlocks. * All signal handlers are either SIG_DFL or SIG_IGN on exec(). * However, if any signal handlers were established on alternate * link maps before the primary link map has been initialized, @@ -645,10 +648,14 @@ signal_init() uberdata_t *udp = curthread->ul_uberdata; struct sigaction *sap; struct sigaction act; + rwlock_t *rwlp; int sig; for (sig = 0; sig < NSIG; sig++) { - udp->siguaction[sig].sig_lock.mutex_magic = MUTEX_MAGIC; + rwlp = &udp->siguaction[sig].sig_lock; + rwlp->rwlock_magic = RWL_MAGIC; + rwlp->mutex.mutex_flag = LOCK_INITED; + rwlp->mutex.mutex_magic = MUTEX_MAGIC; sap = &udp->siguaction[sig].sig_uaction; if (sap->sa_sigaction != SIG_DFL && sap->sa_sigaction != SIG_IGN && @@ -694,13 +701,13 @@ void setup_cancelsig(int sig) { uberdata_t *udp = curthread->ul_uberdata; - mutex_t *mp = &udp->siguaction[sig].sig_lock; + rwlock_t *rwlp = &udp->siguaction[sig].sig_lock; struct sigaction act; ASSERT(sig == SIGCANCEL || sig == SIGAIOCANCEL); - lmutex_lock(mp); + lrw_rdlock(rwlp); act = udp->siguaction[sig].sig_uaction; - lmutex_unlock(mp); + lrw_unlock(rwlp); if (act.sa_sigaction == SIG_DFL || act.sa_sigaction == SIG_IGN) act.sa_flags = SA_SIGINFO; |