diff options
| author | pgoyette <pgoyette@NetBSD.org> | 2015-04-23 23:22:03 +0000 |
|---|---|---|
| committer | pgoyette <pgoyette@NetBSD.org> | 2015-04-23 23:22:03 +0000 |
| commit | 9f231187c1d8df2d05b1bcee93165ee5444fd5ea (patch) | |
| tree | fb54eb93d84c615fe2f472ca27bf04a2958efe70 /sys/dev/sysmon/sysmon_taskq.c | |
| parent | ce2fe0463235a4283d8c2b14b669728e67f7f7e9 (diff) | |
Modularize sysmon and its components
Diffstat (limited to 'sys/dev/sysmon/sysmon_taskq.c')
| -rw-r--r-- | sys/dev/sysmon/sysmon_taskq.c | 62 |
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; +} |
