Initial version of API for creating kernel threads (likely to change somewhat

in the future):
- New function, fork_kthread(), takes entry point, argument for entry point,
  and comment for new proc.  May be called by any context, will fork the
  thread from proc0 (requires slight changes to cpu_fork()).
- cpu_set_kpc() now takes a third argument, a void *arg to pass to the
  thread entry point.  Thread entry point now takes void * instead of
  struct proc *.
- Create the pagedaemon and reaper kernel threads using fork_kthread().
This commit is contained in:
thorpej 1998-11-11 06:34:43 +00:00
parent c7a1452687
commit 6956a57584
4 changed files with 81 additions and 35 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_main.c,v 1.134 1998/10/19 22:19:26 tron Exp $ */
/* $NetBSD: init_main.c,v 1.135 1998/11/11 06:34:43 thorpej Exp $ */
/*
* Copyright (c) 1995 Christopher G. Demetriou. All rights reserved.
@ -136,9 +136,9 @@ struct timeval boottime;
struct timeval runtime;
static void check_console __P((struct proc *p));
static void start_init __P((struct proc *));
static void start_pagedaemon __P((struct proc *));
static void start_reaper __P((struct proc *));
static void start_init __P((void *));
static void start_pagedaemon __P((void *));
static void start_reaper __P((void *));
void main __P((void));
extern char sigcode[], esigcode[];
@ -415,17 +415,15 @@ main()
/* Create process 1 (init(8)). */
if (fork1(p, 0, NULL, &p2))
panic("fork init");
cpu_set_kpc(p2, start_init);
cpu_set_kpc(p2, start_init, p2);
/* Create process 2 (the pageout daemon). */
if (fork1(p, FORK_SHAREVM, NULL, &p2))
panic("fork pager");
cpu_set_kpc(p2, start_pagedaemon);
/* Create process 2, the pageout daemon kernel thread. */
if (fork_kthread(start_pagedaemon, NULL, NULL, "pagedaemon"))
panic("fork pagedaemon");
/* Create process 3 (the process reaper). */
if (fork1(p, FORK_SHAREVM, NULL, &p2))
/* Create process 3, the process reaper kernel thread. */
if (fork_kthread(start_reaper, NULL, NULL, "reaper"))
panic("fork reaper");
cpu_set_kpc(p2, start_reaper);
/* The scheduler is an infinite loop. */
#if defined(UVM)
@ -468,9 +466,10 @@ static char *initpaths[] = {
* The program is invoked with one argument containing the boot flags.
*/
static void
start_init(p)
struct proc *p;
start_init(arg)
void *arg;
{
struct proc *p = arg;
vaddr_t addr;
struct sys_execve_args /* {
syscallarg(const char *) path;
@ -588,16 +587,12 @@ start_init(p)
panic("no init");
}
/* ARGSUSED */
static void
start_pagedaemon(p)
struct proc *p;
start_pagedaemon(arg)
void *arg;
{
/*
* Now in process 2.
*/
p->p_flag |= P_INMEM | P_SYSTEM; /* XXX */
memcpy(curproc->p_comm, "pagedaemon", sizeof("pagedaemon"));
#if defined(UVM)
uvm_pageout();
#else
@ -606,16 +601,12 @@ start_pagedaemon(p)
/* NOTREACHED */
}
/* ARGSUSED */
static void
start_reaper(p)
struct proc *p;
start_reaper(arg)
void *arg;
{
/*
* Now in process 3.
*/
p->p_flag |= P_INMEM | P_SYSTEM; /* XXX */
memcpy(curproc->p_comm, "reaper", sizeof("reaper"));
reaper();
/* NOTREACHED */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_fork.c,v 1.48 1998/09/08 23:50:14 thorpej Exp $ */
/* $NetBSD: kern_fork.c,v 1.49 1998/11/11 06:34:43 thorpej Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@ -61,6 +61,13 @@
#include <sys/syscallargs.h>
/*
* note that stdarg.h and the ansi style va_start macro is used for both
* ansi and traditional c complers.
* XXX: this requires that stdarg.h define: va_alist and va_dcl
*/
#include <machine/stdarg.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
@ -111,6 +118,52 @@ sys___vfork14(p, v, retval)
return (fork1(p, FORK_PPWAIT|FORK_SHAREVM, retval, NULL));
}
/*
* Fork a kernel thread. Any process can request this to be done.
* The VM space and limits, etc. will be shared with proc0.
*/
int
#ifdef __STDC__
fork_kthread(void (*func)(void *), void *arg,
struct proc **newpp, const char *fmt, ...)
#else
fork_kthread(func, arg, newpp, fmt, va_alist)
void (*func) __P((void *));
void *arg;
struct proc **newpp;
const char *fmt;
va_dcl
#endif
{
struct proc *p2;
int error;
va_list ap;
/* First, create the new process. */
error = fork1(&proc0, FORK_SHAREVM, NULL, &p2);
if (error)
return (error);
/*
* Mark it as a system process and not a candidate for
* swapping.
*/
p2->p_flag |= P_INMEM | P_SYSTEM; /* XXX */
/* Name it as specified. */
va_start(ap, fmt);
vsprintf(p2->p_comm, fmt, ap);
va_end(ap);
/* Arrange for it to start at the specified function. */
cpu_set_kpc(p2, func, arg);
/* All done! */
if (newpp != NULL)
*newpp = p2;
return (0);
}
int
fork1(p1, flags, retval, rnewprocp)
register struct proc *p1;
@ -121,7 +174,7 @@ fork1(p1, flags, retval, rnewprocp)
register struct proc *p2;
register uid_t uid;
struct proc *newproc;
int count;
int count, s;
vaddr_t uaddr;
static int nextpid, pidchecked = 0;
@ -336,12 +389,12 @@ again:
/*
* Make child runnable, set start time, and add to run queue.
*/
(void) splstatclock();
s = splstatclock();
p2->p_stats->p_start = time;
p2->p_acflag = AFORK;
p2->p_stat = SRUN;
setrunqueue(p2);
(void) spl0();
splx(s);
/*
* Now can be swapped.

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.67 1998/10/19 11:51:53 pk Exp $ */
/* $NetBSD: proc.h,v 1.68 1998/11/11 06:34:43 thorpej Exp $ */
/*-
* Copyright (c) 1986, 1989, 1991, 1993
@ -360,6 +360,8 @@ void reaper __P((void));
void exit1 __P((struct proc *, int));
void exit2 __P((struct proc *));
int fork1 __P((struct proc *, int, register_t *, struct proc **));
int fork_kthread __P((void (*)(void *), void *, struct proc **,
const char *, ...));
void kmeminit __P((void));
void rqinit __P((void));
int groupmember __P((gid_t, struct ucred *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: systm.h,v 1.83 1998/10/29 21:22:33 jonathan Exp $ */
/* $NetBSD: systm.h,v 1.84 1998/11/11 06:34:43 thorpej Exp $ */
/*-
* Copyright (c) 1982, 1988, 1991, 1993
@ -295,7 +295,7 @@ void consinit __P((void));
void cpu_startup __P((void));
void cpu_rootconf __P((void));
void cpu_dumpconf __P((void));
void cpu_set_kpc __P((struct proc *, void (*)(struct proc *)));
void cpu_set_kpc __P((struct proc *, void (*)(void *), void *));
#ifdef GPROF