diff options
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/sysmon/sysmon_envsys.c | 32 | ||||
| -rw-r--r-- | sys/dev/sysmon/sysmonvar.h | 5 |
2 files changed, 28 insertions, 9 deletions
diff --git a/sys/dev/sysmon/sysmon_envsys.c b/sys/dev/sysmon/sysmon_envsys.c index 97707ca4ba4..c535a4d2391 100644 --- a/sys/dev/sysmon/sysmon_envsys.c +++ b/sys/dev/sysmon/sysmon_envsys.c @@ -1,4 +1,4 @@ -/* $NetBSD: sysmon_envsys.c,v 1.6 2003/06/29 22:30:50 fvdl Exp $ */ +/* $NetBSD: sysmon_envsys.c,v 1.7 2003/08/11 14:24:41 yamt Exp $ */ /*- * Copyright (c) 2000 Zembu Labs, Inc. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.6 2003/06/29 22:30:50 fvdl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.7 2003/08/11 14:24:41 yamt Exp $"); #include <sys/param.h> #include <sys/conf.h> @@ -244,6 +244,7 @@ sysmon_envsys_register(struct sysmon_envsys *sme) { int error = 0; + KASSERT((sme->sme_flags & SME_FLAG_BUSY) == 0); simple_lock(&sysmon_envsys_list_slock); if (sme->sme_envsys_version != SYSMON_ENVSYS_VERSION) { @@ -270,6 +271,9 @@ sysmon_envsys_unregister(struct sysmon_envsys *sme) { simple_lock(&sysmon_envsys_list_slock); + while (sme->sme_flags & SME_FLAG_BUSY) { + ltsleep(sme, PWAIT, "smeunreg", 0, &sysmon_envsys_list_slock); + } LIST_REMOVE(sme, sme_list); simple_unlock(&sysmon_envsys_list_slock); } @@ -277,8 +281,8 @@ sysmon_envsys_unregister(struct sysmon_envsys *sme) /* * sysmon_envsys_find: * - * Find an ENVSYS device. The list remains locked upon - * a match. + * Find an ENVSYS device. + * the found device should be sysmon_envsys_release'ed by the caller. */ struct sysmon_envsys * sysmon_envsys_find(u_int idx) @@ -286,16 +290,23 @@ sysmon_envsys_find(u_int idx) struct sysmon_envsys *sme; simple_lock(&sysmon_envsys_list_slock); - +again: for (sme = LIST_FIRST(&sysmon_envsys_list); sme != NULL; sme = LIST_NEXT(sme, sme_list)) { if (idx >= sme->sme_fsensor && - idx < (sme->sme_fsensor + sme->sme_nsensors)) - return (sme); + idx < (sme->sme_fsensor + sme->sme_nsensors)) { + if (sme->sme_flags & SME_FLAG_BUSY) { + ltsleep(sme, PWAIT, "smefind", 0, + &sysmon_envsys_list_slock); + goto again; + } + sme->sme_flags |= SME_FLAG_BUSY; + break; + } } simple_unlock(&sysmon_envsys_list_slock); - return (NULL); + return sme; } /* @@ -308,5 +319,10 @@ void sysmon_envsys_release(struct sysmon_envsys *sme) { + KASSERT(sme->sme_flags & SME_FLAG_BUSY); + + simple_lock(&sysmon_envsys_list_slock); + sme->sme_flags &= ~SME_FLAG_BUSY; + wakeup(sme); simple_unlock(&sysmon_envsys_list_slock); } diff --git a/sys/dev/sysmon/sysmonvar.h b/sys/dev/sysmon/sysmonvar.h index d3d48a42bfd..721e9b55fcf 100644 --- a/sys/dev/sysmon/sysmonvar.h +++ b/sys/dev/sysmon/sysmonvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sysmonvar.h,v 1.8 2003/06/29 22:30:51 fvdl Exp $ */ +/* $NetBSD: sysmonvar.h,v 1.9 2003/08/11 14:24:41 yamt Exp $ */ /*- * Copyright (c) 2000 Zembu Labs, Inc. @@ -69,8 +69,11 @@ struct sysmon_envsys { u_int sme_fsensor; /* sensor index base, from sysmon */ u_int sme_nsensors; /* sensor count, from driver */ + int sme_flags; }; +#define SME_FLAG_BUSY 0x00000001 /* sme is busy */ + #define SME_SENSOR_IDX(sme, idx) ((idx) - (sme)->sme_fsensor) int sysmonopen_envsys(dev_t, int, int, struct proc *); |
