summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sysctl.c
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2002-04-02 04:20:38 +0000
committeralfred <alfred@FreeBSD.org>2002-04-02 04:20:38 +0000
commit4a63b9d69ccbf1d5d4c34fdbd209efd9b8828b62 (patch)
tree13da819d57a83404acc80d496a3a7781c41828d2 /sys/kern/kern_sysctl.c
parentcb408d85e76131d8ac5262acf46420d22794ca11 (diff)
downloadFreeBSD-src-4a63b9d69ccbf1d5d4c34fdbd209efd9b8828b62.zip
FreeBSD-src-4a63b9d69ccbf1d5d4c34fdbd209efd9b8828b62.tar.gz
Use sx locks instead of flags+tsleep locks.
Submitted by: Jonathan Mini <mini@haikugeek.com>
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r--sys/kern/kern_sysctl.c42
1 files changed, 11 insertions, 31 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 6938706..e3e1bc6 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -50,6 +50,7 @@
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/sx.h>
#include <sys/sysproto.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -60,11 +61,11 @@ static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids");
/*
* Locking and stats
*/
-static struct sysctl_lock {
- int sl_lock;
- int sl_want;
- int sl_locked;
-} memlock;
+static struct sx memlock;
+
+#define MEMLOCK_LOCK() sx_xlock(&memlock)
+#define MEMLOCK_UNLOCK() sx_xunlock(&memlock)
+#define MEMLOCK_INIT() sx_init(&memlock, "sysctl memlock")
static int sysctl_root(SYSCTL_HANDLER_ARGS);
@@ -396,6 +397,7 @@ sysctl_register_all(void *arg)
{
struct sysctl_oid **oidp;
+ MEMLOCK_INIT();
SET_FOREACH(oidp, sysctl_set)
sysctl_register_oid(*oidp);
}
@@ -899,25 +901,14 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
req.newfunc = sysctl_new_kernel;
req.lock = 1;
- /* XXX this should probably be done in a general way */
- while (memlock.sl_lock) {
- memlock.sl_want = 1;
- (void) tsleep((caddr_t)&memlock, PRIBIO+1, "sysctl", 0);
- memlock.sl_locked++;
- }
- memlock.sl_lock = 1;
+ MEMLOCK_LOCK();
error = sysctl_root(0, name, namelen, &req);
if (req.lock == 2)
vsunlock(req.oldptr, req.oldlen);
- memlock.sl_lock = 0;
-
- if (memlock.sl_want) {
- memlock.sl_want = 0;
- wakeup((caddr_t)&memlock);
- }
+ MEMLOCK_UNLOCK();
if (error && error != ENOMEM)
return (error);
@@ -1187,13 +1178,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
req.newfunc = sysctl_new_user;
req.lock = 1;
- /* XXX this should probably be done in a general way */
- while (memlock.sl_lock) {
- memlock.sl_want = 1;
- (void) tsleep((caddr_t)&memlock, PRIBIO+1, "sysctl", 0);
- memlock.sl_locked++;
- }
- memlock.sl_lock = 1;
+ MEMLOCK_LOCK();
do {
req2 = req;
@@ -1204,12 +1189,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
if (req.lock == 2)
vsunlock(req.oldptr, req.oldlen);
- memlock.sl_lock = 0;
-
- if (memlock.sl_want) {
- memlock.sl_want = 0;
- wakeup((caddr_t)&memlock);
- }
+ MEMLOCK_UNLOCK();
if (error && error != ENOMEM)
return (error);
OpenPOWER on IntegriCloud