diff options
author | Roger A. Faulkner <Roger.Faulkner@Sun.COM> | 2009-10-27 10:50:50 -0700 |
---|---|---|
committer | Roger A. Faulkner <Roger.Faulkner@Sun.COM> | 2009-10-27 10:50:50 -0700 |
commit | db94676fbd90b0affb8474a2af4e10718ba3136d (patch) | |
tree | b170ed9a06fd52199be2e3131a45f55aba80100a /usr/src/lib | |
parent | b6ee1ffc437dfc218c4fe37ab7c30ffb523e04cd (diff) | |
download | illumos-gate-db94676fbd90b0affb8474a2af4e10718ba3136d.tar.gz |
6895172 CR 6762445 was too aggressive; signals are blocked in lwp_mutex_lock()
Diffstat (limited to 'usr/src/lib')
-rw-r--r-- | usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c | 23 | ||||
-rw-r--r-- | usr/src/lib/libc/common/sys/syslwp.s | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/thr_uberdata.h | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/lwp.c | 9 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/lwp_cond.c | 13 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/synch.c | 18 |
6 files changed, 36 insertions, 35 deletions
diff --git a/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c b/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c index 9afa5d3d92..8cb27e158b 100644 --- a/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c +++ b/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c @@ -1233,6 +1233,25 @@ s10_lwp_private(sysret_t *rval, int cmd, int which, uintptr_t base) #endif /* __x86 */ /* + * The Opensolaris versions of lwp_mutex_timedlock() and lwp_mutex_trylock() + * add an extra argument to the interfaces, a uintptr_t value for the mutex's + * mutex_owner field. The Solaris 10 libc assigns the mutex_owner field at + * user-level, so we just make the extra argument be zero in both syscalls. + */ + +static int +s10_lwp_mutex_timedlock(sysret_t *rval, lwp_mutex_t *lp, timespec_t *tsp) +{ + return (__systemcall(rval, SYS_lwp_mutex_timedlock + 1024, lp, tsp, 0)); +} + +static int +s10_lwp_mutex_trylock(sysret_t *rval, lwp_mutex_t *lp) +{ + return (__systemcall(rval, SYS_lwp_mutex_trylock + 1024, lp, 0)); +} + +/* * If the emul_global_zone flag is set then emulate some aspects of the * zone system call. In particular, emulate the global zone ID on the * ZONE_LOOKUP subcommand and emulate some of the global zone attributes @@ -1775,7 +1794,7 @@ s10_sysent_table_t s10_sysent_table[] = { NOSYS, /* 207 */ NOSYS, /* 208 */ NOSYS, /* 209 */ - NOSYS, /* 210 */ + EMULATE(s10_lwp_mutex_timedlock, 2 | RV_DEFAULT), /* 210 */ NOSYS, /* 211 */ NOSYS, /* 212 */ NOSYS, /* 213 */ @@ -1820,7 +1839,7 @@ s10_sysent_table_t s10_sysent_table[] = { NOSYS, /* 248 */ NOSYS, /* 249 */ NOSYS, /* 250 */ - NOSYS, /* 251 */ + EMULATE(s10_lwp_mutex_trylock, 1 | RV_DEFAULT), /* 251 */ NOSYS, /* 252 */ NOSYS, /* 253 */ NOSYS, /* 254 */ diff --git a/usr/src/lib/libc/common/sys/syslwp.s b/usr/src/lib/libc/common/sys/syslwp.s index 38ab3e41c0..3d04466188 100644 --- a/usr/src/lib/libc/common/sys/syslwp.s +++ b/usr/src/lib/libc/common/sys/syslwp.s @@ -107,7 +107,7 @@ /* * int - * ___lwp_mutex_timedlock(lwp_mutex_t *, timespec_t *) + * ___lwp_mutex_timedlock(lwp_mutex_t *, timespec_t *, uintptr_t) */ SYSREENTRY(___lwp_mutex_timedlock) SYSTRAP_RVAL1(lwp_mutex_timedlock) @@ -205,7 +205,7 @@ /* * int - * ___lwp_mutex_trylock(lwp_mutex_t *mp) + * ___lwp_mutex_trylock(lwp_mutex_t *mp, uintptr_t) */ ENTRY(___lwp_mutex_trylock) SYSTRAP_RVAL1(lwp_mutex_trylock) diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h index 981a41ef8d..4d1272105c 100644 --- a/usr/src/lib/libc/inc/thr_uberdata.h +++ b/usr/src/lib/libc/inc/thr_uberdata.h @@ -1417,8 +1417,8 @@ extern id_t getparam(idtype_t, id_t, int *, struct sched_param *); * System call wrappers (direct interfaces to the kernel) */ extern int ___lwp_mutex_register(mutex_t *, mutex_t **); -extern int ___lwp_mutex_trylock(mutex_t *); -extern int ___lwp_mutex_timedlock(mutex_t *, timespec_t *); +extern int ___lwp_mutex_trylock(mutex_t *, ulwp_t *); +extern int ___lwp_mutex_timedlock(mutex_t *, timespec_t *, ulwp_t *); extern int ___lwp_mutex_unlock(mutex_t *); extern int ___lwp_mutex_wakeup(mutex_t *, int); extern int ___lwp_cond_wait(cond_t *, mutex_t *, timespec_t *, int); diff --git a/usr/src/lib/libc/port/sys/lwp.c b/usr/src/lib/libc/port/sys/lwp.c index cd33da8464..46ba41c070 100644 --- a/usr/src/lib/libc/port/sys/lwp.c +++ b/usr/src/lib/libc/port/sys/lwp.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "lint.h" #include "thr_uberdata.h" #include <sys/types.h> @@ -35,15 +33,12 @@ #include <sys/synch32.h> #include <sys/lwp.h> -extern int ___lwp_mutex_timedlock(mutex_t *, timespec_t *); -extern int ___lwp_sema_timedwait(lwp_sema_t *, timespec_t *, int); - int _lwp_mutex_lock(mutex_t *mp) { if (set_lock_byte(&mp->mutex_lockw) == 0) return (0); - return (___lwp_mutex_timedlock(mp, NULL)); + return (___lwp_mutex_timedlock(mp, NULL, NULL)); } int diff --git a/usr/src/lib/libc/port/sys/lwp_cond.c b/usr/src/lib/libc/port/sys/lwp_cond.c index 9f0c4da3b8..b9bac46381 100644 --- a/usr/src/lib/libc/port/sys/lwp_cond.c +++ b/usr/src/lib/libc/port/sys/lwp_cond.c @@ -20,24 +20,19 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include "lint.h" +#include "thr_uberdata.h" #include <sys/types.h> - #include <time.h> #include <errno.h> #include <synch.h> #include <sys/synch32.h> #include <pthread.h> -extern int ___lwp_cond_wait(lwp_cond_t *, lwp_mutex_t *, timespec_t *, int); -extern int ___lwp_mutex_timedlock(lwp_mutex_t *, timespec_t *); - int _lwp_cond_wait(cond_t *cv, mutex_t *mp) { @@ -45,7 +40,7 @@ _lwp_cond_wait(cond_t *cv, mutex_t *mp) error = ___lwp_cond_wait(cv, mp, NULL, 0); if (mp->mutex_type & (PTHREAD_PRIO_INHERIT|PTHREAD_PRIO_PROTECT)) - (void) ___lwp_mutex_timedlock(mp, NULL); + (void) ___lwp_mutex_timedlock(mp, NULL, NULL); else (void) _lwp_mutex_lock(mp); return (error); @@ -61,7 +56,7 @@ _lwp_cond_reltimedwait(cond_t *cv, mutex_t *mp, timespec_t *relts) return (EINVAL); error = ___lwp_cond_wait(cv, mp, relts, 0); if (mp->mutex_type & (PTHREAD_PRIO_INHERIT|PTHREAD_PRIO_PROTECT)) - (void) ___lwp_mutex_timedlock(mp, NULL); + (void) ___lwp_mutex_timedlock(mp, NULL, NULL); else (void) _lwp_mutex_lock(mp); return (error); diff --git a/usr/src/lib/libc/port/threads/synch.c b/usr/src/lib/libc/port/threads/synch.c index 9fac80b0f8..a7c4aed9ef 100644 --- a/usr/src/lib/libc/port/threads/synch.c +++ b/usr/src/lib/libc/port/threads/synch.c @@ -443,8 +443,7 @@ spin_lock_set(mutex_t *mp) * Give up and block in the kernel for the mutex. */ INCR32(self->ul_spin_lock_sleep); - (void) ___lwp_mutex_timedlock(mp, NULL); - mp->mutex_owner = (uintptr_t)self; + (void) ___lwp_mutex_timedlock(mp, NULL, self); } void @@ -1002,14 +1001,12 @@ mutex_lock_kernel(mutex_t *mp, timespec_t *tsp, tdb_mutex_stats_t *msp) DTRACE_PROBE1(plockstat, mutex__block, mp); - /* defer signals until the assignment of mp->mutex_owner */ - sigoff(self); for (;;) { /* * A return value of EOWNERDEAD or ELOCKUNMAPPED * means we successfully acquired the lock. */ - if ((error = ___lwp_mutex_timedlock(mp, tsp)) != 0 && + if ((error = ___lwp_mutex_timedlock(mp, tsp, self)) != 0 && error != EOWNERDEAD && error != ELOCKUNMAPPED) { acquired = 0; break; @@ -1022,19 +1019,16 @@ mutex_lock_kernel(mutex_t *mp, timespec_t *tsp, tdb_mutex_stats_t *msp) */ enter_critical(self); if (mp->mutex_ownerpid == udp->pid) { - mp->mutex_owner = (uintptr_t)self; exit_critical(self); acquired = 1; break; } exit_critical(self); } else { - mp->mutex_owner = (uintptr_t)self; acquired = 1; break; } } - sigon(self); if (msp) msp->mutex_sleep_time += gethrtime() - begin_sleep; @@ -1042,6 +1036,7 @@ mutex_lock_kernel(mutex_t *mp, timespec_t *tsp, tdb_mutex_stats_t *msp) self->ul_sp = 0; if (acquired) { + ASSERT(mp->mutex_owner == (uintptr_t)self); DTRACE_PROBE2(plockstat, mutex__blocked, mp, 1); DTRACE_PROBE3(plockstat, mutex__acquire, mp, 0, 0); } else { @@ -1065,13 +1060,12 @@ mutex_trylock_kernel(mutex_t *mp) int error; int acquired; - sigoff(self); for (;;) { /* * A return value of EOWNERDEAD or ELOCKUNMAPPED * means we successfully acquired the lock. */ - if ((error = ___lwp_mutex_trylock(mp)) != 0 && + if ((error = ___lwp_mutex_trylock(mp, self)) != 0 && error != EOWNERDEAD && error != ELOCKUNMAPPED) { acquired = 0; break; @@ -1084,21 +1078,19 @@ mutex_trylock_kernel(mutex_t *mp) */ enter_critical(self); if (mp->mutex_ownerpid == udp->pid) { - mp->mutex_owner = (uintptr_t)self; exit_critical(self); acquired = 1; break; } exit_critical(self); } else { - mp->mutex_owner = (uintptr_t)self; acquired = 1; break; } } - sigon(self); if (acquired) { + ASSERT(mp->mutex_owner == (uintptr_t)self); DTRACE_PROBE3(plockstat, mutex__acquire, mp, 0, 0); } else if (error != EBUSY) { DTRACE_PROBE2(plockstat, mutex__error, mp, error); |