summaryrefslogtreecommitdiff
path: root/sys/dev/sysmon/sysmon_taskq.c
diff options
context:
space:
mode:
authorpgoyette <pgoyette@NetBSD.org>2015-04-23 23:22:03 +0000
committerpgoyette <pgoyette@NetBSD.org>2015-04-23 23:22:03 +0000
commit9f231187c1d8df2d05b1bcee93165ee5444fd5ea (patch)
treefb54eb93d84c615fe2f472ca27bf04a2958efe70 /sys/dev/sysmon/sysmon_taskq.c
parentce2fe0463235a4283d8c2b14b669728e67f7f7e9 (diff)
Modularize sysmon and its components
Diffstat (limited to 'sys/dev/sysmon/sysmon_taskq.c')
-rw-r--r--sys/dev/sysmon/sysmon_taskq.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/sys/dev/sysmon/sysmon_taskq.c b/sys/dev/sysmon/sysmon_taskq.c
index 4d145715936..2bf1b050aee 100644
--- a/sys/dev/sysmon/sysmon_taskq.c
+++ b/sys/dev/sysmon/sysmon_taskq.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sysmon_taskq.c,v 1.14 2008/09/05 22:06:52 gmcgarry Exp $ */
+/* $NetBSD: sysmon_taskq.c,v 1.15 2015/04/23 23:22:03 pgoyette Exp $ */
/*
* Copyright (c) 2001, 2003 Wasabi Systems, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysmon_taskq.c,v 1.14 2008/09/05 22:06:52 gmcgarry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysmon_taskq.c,v 1.15 2015/04/23 23:22:03 pgoyette Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: sysmon_taskq.c,v 1.14 2008/09/05 22:06:52 gmcgarry E
#include <sys/proc.h>
#include <sys/kthread.h>
#include <sys/systm.h>
+#include <sys/module.h>
#include <dev/sysmon/sysmon_taskq.h>
@@ -71,15 +72,36 @@ static int sysmon_task_queue_cleanup_sem;
static struct lwp *sysmon_task_queue_lwp;
static void sysmon_task_queue_thread(void *);
+MODULE(MODULE_CLASS_MISC, sysmon_taskq, NULL);
+
+/*
+ * XXX Normally, all initialization would be handled as part of
+ * the module(9) framework. However, there are a number of
+ * users of the sysmon_taskq facility that are not modular,
+ * and these can directly call sysmon_task_queue_init()
+ * directly. To accomodate these non-standard users, we
+ * make sure that sysmon_task_queue_init() handles multiple
+ * invocations. And we also ensure that, if any non-module
+ * user exists, we don't allow the module to be unloaded.
+ * (We can't use module_hold() for this, since the module(9)
+ * framework itself isn't necessarily initialized yet.)
+ */
+
+/*
+ * sysmon_task_queue_preinit:
+ *
+ * Early one-time initialization of task-queue
+ */
void
sysmon_task_queue_preinit(void)
{
+
mutex_init(&sysmon_task_queue_mtx, MUTEX_DEFAULT, IPL_VM);
mutex_init(&sysmon_task_queue_init_mtx, MUTEX_DEFAULT, IPL_NONE);
cv_init(&sysmon_task_queue_cv, "smtaskq");
+ sysmon_task_queue_initialized = 0;
}
-
/*
* sysmon_task_queue_init:
*
@@ -91,12 +113,11 @@ sysmon_task_queue_init(void)
int error;
mutex_enter(&sysmon_task_queue_init_mtx);
- if (sysmon_task_queue_initialized) {
+ if (sysmon_task_queue_initialized++) {
mutex_exit(&sysmon_task_queue_init_mtx);
return;
}
- sysmon_task_queue_initialized = 1;
mutex_exit(&sysmon_task_queue_init_mtx);
error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
@@ -117,6 +138,9 @@ void
sysmon_task_queue_fini(void)
{
+ if (sysmon_task_queue_initialized > 1)
+ return EBUSY;
+
mutex_enter(&sysmon_task_queue_mtx);
sysmon_task_queue_cleanup_sem = 1;
@@ -209,3 +233,31 @@ sysmon_task_queue_sched(u_int pri, void (*func)(void *), void *arg)
return 0;
}
+
+static
+int
+sysmon_taskq_modcmd(modcmd_t cmd, void *arg)
+{
+ int ret;
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+#ifdef _MODULE
+ sysmon_task_queue_preinit();
+#endif
+ sysmon_task_queue_init();
+ ret = 0;
+ break;
+
+ case MODULE_CMD_FINI:
+ sysmon_task_queue_fini();
+ ret = 0;
+ break;
+
+ case MODULE_CMD_STAT:
+ default:
+ ret = ENOTTY;
+ }
+
+ return ret;
+}