summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2003-03-24 21:15:35 +0000
committerjhb <jhb@FreeBSD.org>2003-03-24 21:15:35 +0000
commit98a481610a9dcb442e9c2e851c6ef2a330027e45 (patch)
tree41fad1aa97bccfd68308cf8a8ff0de8b8f243493 /sys/kern
parent01298a9735ccfad61628107327cfb25e49f8248b (diff)
downloadFreeBSD-src-98a481610a9dcb442e9c2e851c6ef2a330027e45.zip
FreeBSD-src-98a481610a9dcb442e9c2e851c6ef2a330027e45.tar.gz
Replace the at_fork, at_exec, and at_exit functions with the slightly more
flexible process_fork, process_exec, and process_exit eventhandlers. This reduces code duplication and also means that I don't have to go duplicate the eventhandler locking three more times for each of at_fork, at_exec, and at_exit. Reviewed by: phk, jake, almost complete silence on arch@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_exec.c61
-rw-r--r--sys/kern/kern_exit.c67
-rw-r--r--sys/kern/kern_fork.c88
-rw-r--r--sys/kern/sysv_sem.c12
-rw-r--r--sys/kern/uipc_sem.c18
-rw-r--r--sys/kern/vfs_aio.c17
6 files changed, 37 insertions, 226 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index a359b75..a8c668b 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -31,6 +31,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/eventhandler.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysproto.h>
@@ -72,25 +73,12 @@
MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments");
-static MALLOC_DEFINE(M_ATEXEC, "atexec", "atexec callback");
-
static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS);
static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS);
static int sysctl_kern_stackprot(SYSCTL_HANDLER_ARGS);
static int kern_execve(struct thread *td, char *fname, char **argv,
char **envv, struct mac *mac_p);
-/*
- * callout list for things to do at exec time
- */
-struct execlist {
- execlist_fn function;
- TAILQ_ENTRY(execlist) next;
-};
-
-TAILQ_HEAD(exec_list_head, execlist);
-static struct exec_list_head exec_list = TAILQ_HEAD_INITIALIZER(exec_list);
-
/* XXX This should be vm_size_t. */
SYSCTL_PROC(_kern, KERN_PS_STRINGS, ps_strings, CTLTYPE_ULONG|CTLFLAG_RD,
NULL, 0, sysctl_kern_ps_strings, "LU", "");
@@ -840,7 +828,6 @@ exec_new_vmspace(imgp, sv)
struct sysentvec *sv;
{
int error;
- struct execlist *ep;
struct proc *p = imgp->proc;
struct vmspace *vmspace = p->p_vmspace;
vm_offset_t stack_addr;
@@ -852,11 +839,7 @@ exec_new_vmspace(imgp, sv)
imgp->vmspace_destroyed = 1;
- /*
- * Perform functions registered with at_exec().
- */
- TAILQ_FOREACH(ep, &exec_list, next)
- (*ep->function)(p);
+ EVENTHANDLER_INVOKE(process_exec, p);
/*
* Blow away entire process VM, if address space not shared,
@@ -1223,43 +1206,3 @@ exec_unregister(execsw_arg)
execsw = newexecsw;
return (0);
}
-
-int
-at_exec(function)
- execlist_fn function;
-{
- struct execlist *ep;
-
-#ifdef INVARIANTS
- /* Be noisy if the programmer has lost track of things */
- if (rm_at_exec(function))
- printf("WARNING: exec callout entry (%p) already present\n",
- function);
-#endif
- ep = malloc(sizeof(*ep), M_ATEXEC, M_NOWAIT);
- if (ep == NULL)
- return (ENOMEM);
- ep->function = function;
- TAILQ_INSERT_TAIL(&exec_list, ep, next);
- return (0);
-}
-
-/*
- * Scan the exec callout list for the given item and remove it.
- * Returns the number of items removed (0 or 1)
- */
-int
-rm_at_exec(function)
- execlist_fn function;
-{
- struct execlist *ep;
-
- TAILQ_FOREACH(ep, &exec_list, next) {
- if (ep->function == function) {
- TAILQ_REMOVE(&exec_list, ep, next);
- free(ep, M_ATEXEC);
- return (1);
- }
- }
- return (0);
-}
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 38af794..c6cb858 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
+#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/lock.h>
@@ -83,22 +84,9 @@
/* Required to be non-static for SysVR4 emulator */
MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status");
-static MALLOC_DEFINE(M_ATEXIT, "atexit", "atexit callback");
-
static int wait1(struct thread *, struct wait_args *, int);
/*
- * callout list for things to do at exit time
- */
-struct exitlist {
- exitlist_fn function;
- TAILQ_ENTRY(exitlist) next;
-};
-
-TAILQ_HEAD(exit_list_head, exitlist);
-static struct exit_list_head exit_list = TAILQ_HEAD_INITIALIZER(exit_list);
-
-/*
* exit --
* Death of process.
*
@@ -121,7 +109,6 @@ sys_exit(struct thread *td, struct sys_exit_args *uap)
void
exit1(struct thread *td, int rv)
{
- struct exitlist *ep;
struct proc *p, *nq, *q;
struct tty *tp;
struct vnode *ttyvp;
@@ -218,9 +205,7 @@ exit1(struct thread *td, int rv)
* e.g. SYSV IPC stuff
* XXX what if one of these generates an error?
*/
- TAILQ_FOREACH(ep, &exit_list, next)
- (*ep->function)(p);
-
+ EVENTHANDLER_INVOKE(process_exit, p);
MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage),
M_ZOMBIE, M_WAITOK);
@@ -798,51 +783,3 @@ proc_reparent(struct proc *child, struct proc *parent)
LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
child->p_pptr = parent;
}
-
-/*
- * The next two functions are to handle adding/deleting items on the
- * exit callout list
- *
- * at_exit():
- * Take the arguments given and put them onto the exit callout list,
- * However first make sure that it's not already there.
- * returns 0 on success.
- */
-
-int
-at_exit(exitlist_fn function)
-{
- struct exitlist *ep;
-
-#ifdef INVARIANTS
- /* Be noisy if the programmer has lost track of things */
- if (rm_at_exit(function))
- printf("WARNING: exit callout entry (%p) already present\n",
- function);
-#endif
- ep = malloc(sizeof(*ep), M_ATEXIT, M_NOWAIT);
- if (ep == NULL)
- return (ENOMEM);
- ep->function = function;
- TAILQ_INSERT_TAIL(&exit_list, ep, next);
- return (0);
-}
-
-/*
- * Scan the exit callout list for the given item and remove it.
- * Returns the number of items removed (0 or 1)
- */
-int
-rm_at_exit(exitlist_fn function)
-{
- struct exitlist *ep;
-
- TAILQ_FOREACH(ep, &exit_list, next) {
- if (ep->function == function) {
- TAILQ_REMOVE(&exit_list, ep, next);
- free(ep, M_ATEXIT);
- return (1);
- }
- }
- return (0);
-}
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 0c24cc6..11a94d9 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -45,6 +45,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
+#include <sys/eventhandler.h>
#include <sys/filedesc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
@@ -76,22 +77,6 @@
#include <sys/user.h>
#include <machine/critical.h>
-static MALLOC_DEFINE(M_ATFORK, "atfork", "atfork callback");
-
-/*
- * These are the stuctures used to create a callout list for things to do
- * when forking a process
- */
-struct forklist {
- forklist_fn function;
- TAILQ_ENTRY(forklist) next;
-};
-
-static struct sx fork_list_lock;
-
-TAILQ_HEAD(forklist_head, forklist);
-static struct forklist_head fork_list = TAILQ_HEAD_INITIALIZER(fork_list);
-
#ifndef _SYS_SYSPROTO_H_
struct fork_args {
int dummy;
@@ -100,14 +85,6 @@ struct fork_args {
int forksleep; /* Place for fork1() to sleep on. */
-static void
-init_fork_list(void *data __unused)
-{
-
- sx_init(&fork_list_lock, "fork list");
-}
-SYSINIT(fork_list, SI_SUB_INTRINSIC, SI_ORDER_ANY, init_fork_list, NULL);
-
/*
* MPSAFE
*/
@@ -237,7 +214,6 @@ fork1(td, flags, pages, procp)
int trypid;
int ok;
static int pidchecked = 0;
- struct forklist *ep;
struct filedesc *fd;
struct proc *p1 = td->td_proc;
struct thread *td2;
@@ -703,11 +679,7 @@ again:
* to adjust anything.
* What if they have an error? XXX
*/
- sx_slock(&fork_list_lock);
- TAILQ_FOREACH(ep, &fork_list, next) {
- (*ep->function)(p1, p2, flags);
- }
- sx_sunlock(&fork_list_lock);
+ EVENTHANDLER_INVOKE(process_fork, p1, p2, flags);
/*
* If RFSTOPPED not requested, make child runnable and add to
@@ -772,62 +744,6 @@ fail:
}
/*
- * The next two functionms are general routines to handle adding/deleting
- * items on the fork callout list.
- *
- * at_fork():
- * Take the arguments given and put them onto the fork callout list,
- * However first make sure that it's not already there.
- * Returns 0 on success or a standard error number.
- */
-
-int
-at_fork(function)
- forklist_fn function;
-{
- struct forklist *ep;
-
-#ifdef INVARIANTS
- /* let the programmer know if he's been stupid */
- if (rm_at_fork(function))
- printf("WARNING: fork callout entry (%p) already present\n",
- function);
-#endif
- ep = malloc(sizeof(*ep), M_ATFORK, M_NOWAIT);
- if (ep == NULL)
- return (ENOMEM);
- ep->function = function;
- sx_xlock(&fork_list_lock);
- TAILQ_INSERT_TAIL(&fork_list, ep, next);
- sx_xunlock(&fork_list_lock);
- return (0);
-}
-
-/*
- * Scan the exit callout list for the given item and remove it..
- * Returns the number of items removed (0 or 1)
- */
-
-int
-rm_at_fork(function)
- forklist_fn function;
-{
- struct forklist *ep;
-
- sx_xlock(&fork_list_lock);
- TAILQ_FOREACH(ep, &fork_list, next) {
- if (ep->function == function) {
- TAILQ_REMOVE(&fork_list, ep, next);
- sx_xunlock(&fork_list_lock);
- free(ep, M_ATFORK);
- return(1);
- }
- }
- sx_xunlock(&fork_list_lock);
- return (0);
-}
-
-/*
* Handle the return of a child process from fork1(). This function
* is called from the MD fork_trampoline() entry point.
*/
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index 7eeb625..bf1eae3 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -13,6 +13,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
+#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/lock.h>
@@ -35,7 +36,7 @@ static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
static void seminit(void);
static int sysvsem_modload(struct module *, int, void *);
static int semunload(void);
-static void semexit_myhook(struct proc *p);
+static void semexit_myhook(void *arg, struct proc *p);
static int sysctl_sema(SYSCTL_HANDLER_ARGS);
static int semvalid(int semid, struct semid_ds *semaptr);
@@ -66,6 +67,7 @@ static struct mtx *sema_mtx; /* semaphore id pool mutexes*/
static struct sem *sem; /* semaphore pool */
SLIST_HEAD(, sem_undo) semu_list; /* list of active undo structures */
static int *semu; /* undo structure pool */
+static eventhandler_tag semexit_tag;
#define SEMUNDO_MTX sem_mtx
#define SEMUNDO_LOCK() mtx_lock(&SEMUNDO_MTX);
@@ -203,8 +205,9 @@ seminit(void)
suptr->un_proc = NULL;
}
SLIST_INIT(&semu_list);
- at_exit(semexit_myhook);
mtx_init(&sem_mtx, "sem", NULL, MTX_DEF);
+ semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
+ EVENTHANDLER_PRI_ANY);
}
static int
@@ -215,10 +218,10 @@ semunload(void)
if (semtot != 0)
return (EBUSY);
+ EVENTHANDLER_DEREGISTER(process_exit, semexit_tag);
free(sem, M_SEM);
free(sema, M_SEM);
free(semu, M_SEM);
- rm_at_exit(semexit_myhook);
for (i = 0; i < seminfo.semmni; i++)
mtx_destroy(&sema_mtx[i]);
mtx_destroy(&sem_mtx);
@@ -1139,7 +1142,8 @@ done2:
* semaphores.
*/
static void
-semexit_myhook(p)
+semexit_myhook(arg, p)
+ void *arg;
struct proc *p;
{
struct sem_undo *suptr;
diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c
index 538ff67..9f59626 100644
--- a/sys/kern/uipc_sem.c
+++ b/sys/kern/uipc_sem.c
@@ -31,6 +31,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
+#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/lock.h>
@@ -57,7 +58,7 @@ static void sem_free(struct ksem *ksnew);
static int sem_perm(struct thread *td, struct ksem *ks);
static void sem_enter(struct proc *p, struct ksem *ks);
static int sem_leave(struct proc *p, struct ksem *ks);
-static void sem_exithook(struct proc *p);
+static void sem_exithook(void *arg, struct proc *p);
static int sem_hasopen(struct thread *td, struct ksem *ks);
static int kern_sem_close(struct thread *td, semid_t id);
@@ -114,6 +115,8 @@ static int nsems = 0;
SYSCTL_DECL(_p1003_1b);
SYSCTL_INT(_p1003_1b, OID_AUTO, nsems, CTLFLAG_RD, &nsems, 0, "");
+static eventhandler_tag sem_exit_tag, sem_exec_tag;
+
#ifdef SEM_DEBUG
#define DP(x) printf x
#else
@@ -769,7 +772,8 @@ err:
}
static void
-sem_exithook(p)
+sem_exithook(arg, p)
+ void *arg;
struct proc *p;
{
struct ksem *ks, *ksnext;
@@ -800,16 +804,18 @@ sem_modload(struct module *module, int cmd, void *arg)
mtx_init(&sem_lock, "sem", "semaphore", MTX_DEF);
p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX);
- at_exec(&sem_exithook);
- at_exit(&sem_exithook);
+ sem_exit_tag = EVENTHANDLER_REGISTER(process_exit, sem_exithook,
+ NULL, EVENTHANDLER_PRI_ANY);
+ sem_exec_tag = EVENTHANDLER_REGISTER(process_exec, sem_exithook,
+ NULL, EVENTHANDLER_PRI_ANY);
break;
case MOD_UNLOAD:
if (nsems != 0) {
error = EOPNOTSUPP;
break;
}
- rm_at_exit(&sem_exithook);
- rm_at_exec(&sem_exithook);
+ EVENTHANDLER_DEREGISTER(process_exit, sem_exit_tag);
+ EVENTHANDLER_DEREGISTER(process_exec, sem_exec_tag);
mtx_destroy(&sem_lock);
break;
case MOD_SHUTDOWN:
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 9532ff2..c014162 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -25,6 +25,7 @@
#include <sys/malloc.h>
#include <sys/bio.h>
#include <sys/buf.h>
+#include <sys/eventhandler.h>
#include <sys/sysproto.h>
#include <sys/filedesc.h>
#include <sys/kernel.h>
@@ -253,7 +254,7 @@ static void aio_process(struct aiocblist *aiocbe);
static int aio_newproc(void);
static int aio_aqueue(struct thread *td, struct aiocb *job, int type);
static void aio_physwakeup(struct buf *bp);
-static void aio_proc_rundown(struct proc *p);
+static void aio_proc_rundown(void *arg, struct proc *p);
static int aio_fphysio(struct aiocblist *aiocbe);
static int aio_qphysio(struct proc *p, struct aiocblist *iocb);
static void aio_daemon(void *uproc);
@@ -278,6 +279,8 @@ static uma_zone_t kaio_zone, aiop_zone, aiocb_zone, aiol_zone, aiolio_zone;
static struct filterops aio_filtops =
{ 0, filt_aioattach, filt_aiodetach, filt_aio };
+static eventhandler_tag exit_tag, exec_tag;
+
/*
* Main operations function for use as a kernel module.
*/
@@ -330,8 +333,10 @@ aio_onceonly(void)
/* XXX: should probably just use so->callback */
aio_swake = &aio_swake_cb;
- at_exit(aio_proc_rundown);
- at_exec(aio_proc_rundown);
+ exit_tag = EVENTHANDLER_REGISTER(process_exit, aio_proc_rundown, NULL,
+ EVENTHANDLER_PRI_ANY);
+ exec_tag = EVENTHANDLER_REGISTER(process_exec, aio_proc_rundown, NULL,
+ EVENTHANDLER_PRI_ANY);
kqueue_add_filteropts(EVFILT_AIO, &aio_filtops);
TAILQ_INIT(&aio_freeproc);
TAILQ_INIT(&aio_activeproc);
@@ -373,8 +378,8 @@ aio_unload(void)
async_io_version = 0;
aio_swake = NULL;
- rm_at_exit(aio_proc_rundown);
- rm_at_exec(aio_proc_rundown);
+ EVENTHANDLER_DEREGISTER(process_exit, exit_tag);
+ EVENTHANDLER_DEREGISTER(process_exec, exec_tag);
kqueue_del_filteropts(EVFILT_AIO);
p31b_setcfg(CTL_P1003_1B_AIO_LISTIO_MAX, -1);
p31b_setcfg(CTL_P1003_1B_AIO_MAX, -1);
@@ -525,7 +530,7 @@ aio_free_entry(struct aiocblist *aiocbe)
* Rundown the jobs for a given process.
*/
static void
-aio_proc_rundown(struct proc *p)
+aio_proc_rundown(void *arg, struct proc *p)
{
int s;
struct kaioinfo *ki;
OpenPOWER on IntegriCloud