-/* $OpenBSD: pmap.c,v 1.64 2014/05/08 19:06:07 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.65 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: pmap.c,v 1.74 1999/11/13 21:32:25 matt Exp $ */
/*
* Copyright (c) 1994, 1998, 1999, 2003 Ludd, University of Lule}, Sweden.
* Avoid to remove ourselves. Logic is designed after uvm_swapout_threads().
*/
-static inline boolean_t
-pmap_vax_swappable(struct proc *p, struct pmap *pm)
-{
- if (p->p_flag & (P_SYSTEM | P_WEXIT)) /* !swappable(p) */
- return FALSE;
- if (p->p_vmspace->vm_map.pmap == pm)
- return FALSE;
- switch (p->p_stat) {
- case SRUN:
- case SSLEEP:
- case SSTOP:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
int
pmap_rmproc(struct pmap *pm)
{
+ struct process *pr, *outpr;
struct pmap *ppm;
- struct proc *p;
- struct proc *outp, *outp2;
- int outpri, outpri2;
+ struct proc *p, *slpp;
+ int outpri;
int didswap = 0;
extern int maxslp;
- outp = outp2 = NULL;
- outpri = outpri2 = 0;
- LIST_FOREACH(p, &allproc, p_list) {
- if (!pmap_vax_swappable(p, pm))
+ outpr = NULL;
+ outpri = 0;
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ if (pr->ps_flags & (PS_SYSTEM | PS_EXITING))
continue;
ppm = p->p_vmspace->vm_map.pmap;
+ if (ppm == pm) /* Don't swap ourself */
+ continue;
if (ppm->pm_p0lr == 0 && ppm->pm_p1lr == NPTEPERREG)
- continue; /* Already swapped */
- switch (p->p_stat) {
- case SRUN:
-#if 0 /* won't pass pmap_vax_swappable() */
- case SONPROC:
-#endif
- if (p->p_swtime > outpri2) {
- outp2 = p;
- outpri2 = p->p_swtime;
+ continue; /* Already swapped */
+
+ /*
+ * slpp: the sleeping or stopped thread in pr with
+ * the smallest p_slptime
+ */
+ slpp = NULL;
+ TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
+ switch (p->p_stat) {
+ case SRUN:
+ case SONPROC:
+ goto next_process;
+
+ case SSLEEP:
+ case SSTOP:
+ if (slpp == NULL ||
+ slpp->p_slptime < p->p_slptime)
+ slpp = p;
+ continue;
}
- continue;
- case SSLEEP:
- case SSTOP:
- if (p->p_slptime >= maxslp) {
+ }
+ if (slpp != NULL) {
+ if (slpp->p_slptime >= maxslp) {
rmspace(ppm);
didswap++;
- } else if (p->p_slptime > outpri) {
- outp = p;
+ } else if (slpp->p_slptime > outpri) {
+ outpr = pr;
outpri = p->p_slptime;
}
- continue;
}
+next_process: ;
}
- if (didswap == 0) {
- if ((p = outp) == NULL)
- p = outp2;
- if (p) {
- rmspace(p->p_vmspace->vm_map.pmap);
- didswap++;
- }
+ if (didswap == 0 && outpr != NULL) {
+ rmspace(outpr->ps_vmspace->vm_map.pmap);
+ didswap++;
}
return didswap;
}
-/* $OpenBSD: init_main.c,v 1.212 2014/05/04 05:03:26 guenther Exp $ */
+/* $OpenBSD: init_main.c,v 1.213 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
siginit(pr);
/* Create the file descriptor table. */
- p->p_fd = fdinit(NULL);
+ p->p_fd = pr->ps_fd = fdinit();
/* Create the limits structures. */
pr->ps_limit = &limit0;
/* Allocate a prototype map so we have something to fork. */
uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
trunc_page(VM_MAX_ADDRESS), TRUE, TRUE);
- p->p_vmspace = &vmspace0;
+ p->p_vmspace = pr->ps_vmspace = &vmspace0;
p->p_addr = proc0paddr; /* XXX */
-/* $OpenBSD: kern_descrip.c,v 1.107 2014/04/12 14:18:11 espie Exp $ */
+/* $OpenBSD: kern_descrip.c,v 1.108 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */
/*
* Build a new filedesc structure.
*/
struct filedesc *
-fdinit(struct proc *p)
+fdinit(void)
{
struct filedesc0 *newfdp;
extern int cmask;
newfdp = pool_get(&fdesc_pool, PR_WAITOK|PR_ZERO);
- if (p != NULL) {
- struct filedesc *fdp = p->p_fd;
-
- newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
- vref(newfdp->fd_fd.fd_cdir);
- newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
- if (newfdp->fd_fd.fd_rdir)
- vref(newfdp->fd_fd.fd_rdir);
- }
rw_init(&newfdp->fd_fd.fd_lock, "fdlock");
/* Create the file descriptor table. */
* Share a filedesc structure.
*/
struct filedesc *
-fdshare(struct proc *p)
+fdshare(struct process *pr)
{
- p->p_fd->fd_refcnt++;
- return (p->p_fd);
+ pr->ps_fd->fd_refcnt++;
+ return (pr->ps_fd);
}
/*
* Copy a filedesc structure.
*/
struct filedesc *
-fdcopy(struct proc *p)
+fdcopy(struct process *pr)
{
- struct filedesc *newfdp, *fdp = p->p_fd;
+ struct filedesc *newfdp, *fdp = pr->ps_fd;
struct file **fpp;
int i;
-/* $OpenBSD: kern_exec.c,v 1.141 2014/04/18 11:51:17 guenther Exp $ */
+/* $OpenBSD: kern_exec.c,v 1.142 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */
/*-
/*
* Map the shared signal code.
*/
-int exec_sigcode_map(struct proc *, struct emul *);
+int exec_sigcode_map(struct process *, struct emul *);
/*
* If non-zero, stackgap_random specifies the upper limit of the random gap size
#endif
char *stack;
struct ps_strings arginfo;
- struct vmspace *vm = p->p_vmspace;
+ struct vmspace *vm = pr->ps_vmspace;
char **tmpfap;
extern struct emul emul_native;
#if NSYSTRACE > 0
/*
* we're committed: any further errors will kill the process, so
* kill the other threads now.
- * XXX wait until threads are reaped to make uvmspace_exec() cheaper?
*/
single_thread_set(p, SINGLE_EXIT, 0);
/*
* Prepare vmspace for remapping. Note that uvmspace_exec can replace
- * p_vmspace!
+ * pr_vmspace!
*/
uvmspace_exec(p, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS);
- vm = p->p_vmspace;
+ vm = pr->ps_vmspace;
/* Now map address space */
vm->vm_taddr = (char *)pack.ep_taddr;
vm->vm_tsize = atop(round_page(pack.ep_tsize));
#endif
/* map the process's signal trampoline code */
- if (exec_sigcode_map(p, pack.ep_emul))
+ if (exec_sigcode_map(pr, pack.ep_emul))
goto free_pack_abort;
#ifdef __HAVE_EXEC_MD_MAP
}
int
-exec_sigcode_map(struct proc *p, struct emul *e)
+exec_sigcode_map(struct process *pr, struct emul *e)
{
vsize_t sz;
uvm_unmap(kernel_map, va, va + round_page(sz));
}
- p->p_p->ps_sigcode = 0; /* no hint */
+ pr->ps_sigcode = 0; /* no hint */
uao_reference(e->e_sigobject);
- if (uvm_map(&p->p_vmspace->vm_map, &p->p_p->ps_sigcode, round_page(sz),
+ if (uvm_map(&pr->ps_vmspace->vm_map, &pr->ps_sigcode, round_page(sz),
e->e_sigobject, 0, 0, UVM_MAPFLAG(UVM_PROT_RX, UVM_PROT_RX,
UVM_INH_SHARE, UVM_ADV_RANDOM, 0))) {
uao_detach(e->e_sigobject);
-/* $OpenBSD: kern_exit.c,v 1.140 2014/04/18 11:51:17 guenther Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.141 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
}
p->p_siglist = 0;
- /*
- * Close open files and release open-file table.
- */
- fdfree(p);
-
if ((p->p_flag & P_THREAD) == 0) {
+ /* close open files and release open-file table */
+ fdfree(p);
+
timeout_del(&pr->ps_realit_to);
#ifdef SYSVSEM
semexit(pr);
atomic_setbits_int(&pr->ps_flags, PS_NOZOMBIE);
}
+ p->p_fd = NULL; /* zap the thread's copy */
+
#if NSYSTRACE > 0
if (ISSET(p->p_flag, P_SYSTRACE))
systrace_exit(p);
* We must do this from a valid thread because doing
* so may block.
*/
- uvm_exit(p);
+ uvm_uarea_free(p);
+ p->p_vmspace = NULL; /* zap the thread's copy */
if (p->p_flag & P_THREAD) {
/* Just a thread */
} else {
struct process *pr = p->p_p;
+ /* Release the rest of the process's vmspace */
+ uvm_exit(pr);
+
if ((pr->ps_flags & PS_NOZOMBIE) == 0) {
/* Process is now a true zombie. */
p->p_stat = SZOMB;
-/* $OpenBSD: kern_fork.c,v 1.166 2014/05/06 11:50:14 mpi Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.167 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
p->p_p = pr;
/*
- * Create signal actions for the child process.
+ * Duplicate sub-structures as needed.
+ * Increase reference counts on shared objects.
*/
+ if (flags & FORK_SHAREFILES)
+ pr->ps_fd = fdshare(parent);
+ else
+ pr->ps_fd = fdcopy(parent);
if (flags & FORK_SIGHAND)
pr->ps_sigacts = sigactsshare(parent);
else
pr->ps_sigacts = sigactsinit(parent);
+ if (flags & FORK_SHAREVM)
+ pr->ps_vmspace = uvmspace_share(parent);
+ else
+ pr->ps_vmspace = uvmspace_fork(parent);
if (parent->ps_flags & PS_PROFIL)
startprofclock(pr);
process_new(p, curpr, flags);
pr = p->p_p;
}
+ p->p_fd = pr->ps_fd;
+ p->p_vmspace = pr->ps_vmspace;
if (pr->ps_flags & PS_SYSTEM)
atomic_setbits_int(&p->p_flag, P_SYSTEM);
- /*
- * Duplicate sub-structures as needed.
- * Increase reference counts on shared objects.
- */
- if (flags & FORK_SHAREFILES)
- p->p_fd = fdshare(curp);
- else
- p->p_fd = fdcopy(curp);
-
if (flags & FORK_PPWAIT) {
atomic_setbits_int(&pr->ps_flags, PS_PPWAIT);
atomic_setbits_int(&curpr->ps_flags, PS_ISPWAIT);
p->p_addr = (struct user *)uaddr;
/*
- * Finish creating the child process. It will return through a
- * different path later.
+ * Finish creating the child thread. cpu_fork() will copy
+ * and update the pcb and make the child ready to run. If
+ * this is a normal user fork, the child will exit directly
+ * to user mode via child_return() on its first time slice
+ * and will not return here. If this is a kernel thread,
+ * the specified entry point will be executed.
*/
- uvm_fork(curp, p, ((flags & FORK_SHAREVM) ? TRUE : FALSE), stack,
- 0, func ? func : child_return, arg ? arg : p);
+ cpu_fork(curp, p, stack, 0, func ? func : child_return, arg ? arg : p);
- vm = p->p_vmspace;
+ vm = pr->ps_vmspace;
if (flags & FORK_FORK) {
forkstat.cntfork++;
-/* $OpenBSD: kern_proc.c,v 1.57 2014/03/30 21:54:48 guenther Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.58 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
TAILQ_NEXT(p, p_runq), p->p_list.le_next, p->p_list.le_prev);
(*pr)(" process=%p user=%p, vmspace=%p\n",
p->p_p, p->p_addr, p->p_vmspace);
- (*pr)(" estcpu=%u, cpticks=%d, pctcpu=%u.%u, swtime=%u\n",
- p->p_estcpu, p->p_cpticks, p->p_pctcpu / 100, p->p_pctcpu % 100,
- p->p_swtime);
+ (*pr)(" estcpu=%u, cpticks=%d, pctcpu=%u.%u\n",
+ p->p_estcpu, p->p_cpticks, p->p_pctcpu / 100, p->p_pctcpu % 100);
(*pr)(" user=%u, sys=%u, intr=%u\n",
p->p_uticks, p->p_sticks, p->p_iticks);
}
-/* $OpenBSD: sched_bsd.c,v 1.33 2013/06/03 16:55:22 guenther Exp $ */
+/* $OpenBSD: sched_bsd.c,v 1.34 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*-
* (if sleeping). We ignore overflow; with 16-bit int's
* (remember them?) overflow takes 45 days.
*/
- p->p_swtime++;
if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
p->p_slptime++;
p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
-/* $OpenBSD: filedesc.h,v 1.27 2014/04/12 14:18:11 espie Exp $ */
+/* $OpenBSD: filedesc.h,v 1.28 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: filedesc.h,v 1.14 1996/04/09 20:55:28 cgd Exp $ */
/*
int fdalloc(struct proc *p, int want, int *result);
void fdexpand(struct proc *);
int falloc(struct proc *p, struct file **resultfp, int *resultfd);
-struct filedesc *fdinit(struct proc *p);
-struct filedesc *fdshare(struct proc *p);
-struct filedesc *fdcopy(struct proc *p);
+struct filedesc *fdinit(void);
+struct filedesc *fdshare(struct process *);
+struct filedesc *fdcopy(struct process *);
void fdfree(struct proc *p);
int fdrelease(struct proc *p, int);
void fdremove(struct filedesc *, int);
-/* $OpenBSD: proc.h,v 1.185 2014/05/04 05:03:26 guenther Exp $ */
+/* $OpenBSD: proc.h,v 1.186 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
struct sigacts *ps_sigacts; /* Signal actions, state */
struct vnode *ps_textvp; /* Vnode of executable. */
+ struct filedesc *ps_fd; /* Ptr to open files structure */
+ struct vmspace *ps_vmspace; /* Address space */
/* The following fields are all zeroed upon creation in process_new. */
#define ps_startzero ps_klist
TAILQ_ENTRY(proc) p_thr_link;/* Threads in a process linkage. */
/* substructures: */
- struct filedesc *p_fd; /* Ptr to open files structure. */
- struct vmspace *p_vmspace; /* Address space. */
+ struct filedesc *p_fd; /* copy of p_p->ps_fd */
+ struct vmspace *p_vmspace; /* copy of p_p->ps_vmspace */
#define p_rlimit p_p->ps_limit->pl_rlimit
int p_flag; /* P_* flags. */
const volatile void *p_wchan;/* Sleep address. */
struct timeout p_sleep_to;/* timeout for tsleep() */
const char *p_wmesg; /* Reason for sleep. */
- fixpt_t p_pctcpu; /* %cpu for this thread during p_swtime */
- u_int p_swtime; /* Time swapped in or out. */
+ fixpt_t p_pctcpu; /* %cpu for this thread */
u_int p_slptime; /* Time since last blocked. */
u_int p_uticks; /* Statclock hits in user mode. */
u_int p_sticks; /* Statclock hits in system mode. */
-/* $OpenBSD: sysctl.h,v 1.144 2014/03/30 21:54:48 guenther Exp $ */
+/* $OpenBSD: sysctl.h,v 1.145 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
u_int32_t p_rtime_sec; /* STRUCT TIMEVAL: Real time. */
u_int32_t p_rtime_usec; /* STRUCT TIMEVAL: Real time. */
int32_t p_cpticks; /* INT: Ticks of cpu time. */
- u_int32_t p_pctcpu; /* FIXPT_T: %cpu for this process during p_swtime */
- u_int32_t p_swtime; /* U_INT: Time swapped in or out. */
+ u_int32_t p_pctcpu; /* FIXPT_T: %cpu for this process */
+ u_int32_t p_swtime; /* unused, always zero */
u_int32_t p_slptime; /* U_INT: Time since last blocked. */
int32_t p_schedflags; /* INT: PSCHED_* flags */
\
if (show_addresses) { \
(kp)->p_paddr = PTRTOINT64(paddr); \
- (kp)->p_fd = PTRTOINT64((p)->p_fd); \
+ (kp)->p_fd = PTRTOINT64((pr)->ps_fd); \
(kp)->p_limit = PTRTOINT64((pr)->ps_limit); \
- (kp)->p_vmspace = PTRTOINT64((p)->p_vmspace); \
+ (kp)->p_vmspace = PTRTOINT64((pr)->ps_vmspace); \
(kp)->p_sigacts = PTRTOINT64((pr)->ps_sigacts); \
(kp)->p_sess = PTRTOINT64((pg)->pg_session); \
(kp)->p_ru = PTRTOINT64((pr)->ps_ru); \
} \
(kp)->p_addr = PTRTOINT64((p)->p_addr); \
(kp)->p_stat = (p)->p_stat; \
- (kp)->p_swtime = (p)->p_swtime; \
(kp)->p_slptime = (p)->p_slptime; \
(kp)->p_holdcnt = 1; \
(kp)->p_priority = (p)->p_priority; \
-/* $OpenBSD: uvm_extern.h,v 1.114 2014/05/06 11:50:14 mpi Exp $ */
+/* $OpenBSD: uvm_extern.h,v 1.115 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $ */
/*
void uvm_chgkprot(caddr_t, size_t, int);
#endif
vaddr_t uvm_uarea_alloc(void);
-void uvm_fork(struct proc *, struct proc *, boolean_t,
- void *, size_t, void (*)(void *), void *);
-void uvm_exit(struct proc *);
+void uvm_uarea_free(struct proc *);
+void uvm_exit(struct process *);
void uvm_init_limits(struct proc *);
boolean_t uvm_kernacc(caddr_t, size_t, int);
void uvmspace_init(struct vmspace *, struct pmap *,
vaddr_t, vaddr_t, boolean_t, boolean_t);
void uvmspace_exec(struct proc *, vaddr_t, vaddr_t);
-struct vmspace *uvmspace_fork(struct vmspace *);
+struct vmspace *uvmspace_fork(struct process *);
void uvmspace_free(struct vmspace *);
-void uvmspace_share(struct proc *, struct proc *);
+struct vmspace *uvmspace_share(struct process *);
/* uvm_meter.c */
-/* $OpenBSD: uvm_glue.c,v 1.64 2014/05/03 22:49:43 guenther Exp $ */
+/* $OpenBSD: uvm_glue.c,v 1.65 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: uvm_glue.c,v 1.44 2001/02/06 19:54:44 eeh Exp $ */
/*
}
/*
- * uvm_fork: fork a virtual address space
+ * uvm_uarea_free: free a dead thread's stack
*
- * - the address space is copied as per parent map's inherit values
- * - if specified, the child gets a new user stack described by
- * stack and stacksize
- * - NOTE: the kernel stack may be at a different location in the child
- * process, and thus addresses of automatic variables may be invalid
- * after cpu_fork returns in the child process. We do nothing here
- * after cpu_fork returns.
- * - XXXCDC: we need a way for this to return a failure value rather
- * than just hang
+ * - the thread passed to us is a dead thread; we
+ * are running on a different context now (the reaper).
*/
void
-uvm_fork(struct proc *p1, struct proc *p2, boolean_t shared, void *stack,
- size_t stacksize, void (*func)(void *), void * arg)
+uvm_uarea_free(struct proc *p)
{
- if (shared == TRUE) {
- p2->p_vmspace = NULL;
- uvmspace_share(p1, p2); /* share vmspace */
- } else
- p2->p_vmspace = uvmspace_fork(p1->p_vmspace); /* fork vmspace */
-
- /*
- * cpu_fork() copy and update the pcb, and make the child ready
- * to run. If this is a normal user fork, the child will exit
- * directly to user mode via child_return() on its first time
- * slice and will not return here. If this is a kernel thread,
- * the specified entry point will be executed.
- */
- cpu_fork(p1, p2, stack, stacksize, func, arg);
+ uvm_km_free(kernel_map, (vaddr_t)p->p_addr, USPACE);
+ p->p_addr = NULL;
}
/*
* uvm_exit: exit a virtual address space
- *
- * - the process passed to us is a dead (pre-zombie) process; we
- * are running on a different context now (the reaper).
- * - we must run in a separate thread because freeing the vmspace
- * of the dead process may block.
*/
void
-uvm_exit(struct proc *p)
+uvm_exit(struct process *pr)
{
- uvmspace_free(p->p_vmspace);
- p->p_vmspace = NULL;
- uvm_km_free(kernel_map, (vaddr_t)p->p_addr, USPACE);
- p->p_addr = NULL;
+ uvmspace_free(pr->ps_vmspace);
+ pr->ps_vmspace = NULL;
}
/*
#define SDB_SWAPOUT 4
#endif
-/*
- * swappable: is process "p" swappable?
- */
-
-#define swappable(p) (((p)->p_flag & (P_SYSTEM | P_WEXIT)) == 0)
/*
* swapout_threads: find threads that can be swapped
void
uvm_swapout_threads(void)
{
- struct proc *p;
- struct proc *outp, *outp2;
- int outpri, outpri2;
+ struct process *pr;
+ struct proc *p, *slpp;
+ struct process *outpr;
+ int outpri;
int didswap = 0;
extern int maxslp;
/* XXXCDC: should move off to uvmexp. or uvm., also in uvm_meter */
#endif
/*
- * outp/outpri : stop/sleep process with largest sleeptime < maxslp
- * outp2/outpri2: the longest resident process (its swap time)
+ * outpr/outpri : stop/sleep process whose most active thread has
+ * the largest sleeptime < maxslp
*/
- outp = outp2 = NULL;
- outpri = outpri2 = 0;
- LIST_FOREACH(p, &allproc, p_list) {
- if (!swappable(p))
+ outpr = NULL;
+ outpri = 0;
+ LIST_FOREACH(pr, &allprocess, ps_list) {
+ if (pr->ps_flags & (PS_SYSTEM | PS_EXITING))
continue;
- switch (p->p_stat) {
- case SRUN:
- if (p->p_swtime > outpri2) {
- outp2 = p;
- outpri2 = p->p_swtime;
+
+ /*
+ * slpp: the sleeping or stopped thread in pr with
+ * the smallest p_slptime
+ */
+ slpp = NULL;
+ TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
+ switch (p->p_stat) {
+ case SRUN:
+ case SONPROC:
+ goto next_process;
+
+ case SSLEEP:
+ case SSTOP:
+ if (slpp == NULL ||
+ slpp->p_slptime < p->p_slptime)
+ slpp = p;
+ continue;
}
- continue;
-
- case SSLEEP:
- case SSTOP:
- if (p->p_slptime >= maxslp) {
- pmap_collect(p->p_vmspace->vm_map.pmap);
+ }
+
+ if (slpp != NULL) {
+ if (slpp->p_slptime >= maxslp) {
+ pmap_collect(pr->ps_vmspace->vm_map.pmap);
didswap++;
- } else if (p->p_slptime > outpri) {
- outp = p;
- outpri = p->p_slptime;
+ } else if (slpp->p_slptime > outpri) {
+ outpr = pr;
+ outpri = slpp->p_slptime;
}
- continue;
}
+next_process: ;
}
/*
* if we are real low on memory since we don't gain much by doing
* it.
*/
- if (didswap == 0 && uvmexp.free <= atop(round_page(USPACE))) {
- if ((p = outp) == NULL)
- p = outp2;
+ if (didswap == 0 && uvmexp.free <= atop(round_page(USPACE)) &&
+ outpr != NULL) {
#ifdef DEBUG
if (swapdebug & SDB_SWAPOUT)
- printf("swapout_threads: no duds, try procp %p\n", p);
+ printf("swapout_threads: no duds, try procpr %p\n",
+ outpr);
#endif
- if (p)
- pmap_collect(p->p_vmspace->vm_map.pmap);
+ pmap_collect(outpr->ps_vmspace->vm_map.pmap);
}
}
-/* $OpenBSD: uvm_map.c,v 1.167 2014/04/13 23:14:15 tedu Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.168 2014/05/15 03:52:25 guenther Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
* uvmspace_share: share a vmspace between two processes
*
* - XXX: no locking on vmspace
- * - used for vfork and threads
+ * - used for vfork
*/
-void
-uvmspace_share(p1, p2)
- struct proc *p1, *p2;
+struct vmspace *
+uvmspace_share(struct process *pr)
{
- p2->p_vmspace = p1->p_vmspace;
- p1->p_vmspace->vm_refcnt++;
+ struct vmspace *vm = pr->ps_vmspace;
+
+ vm->vm_refcnt++;
+ return vm;
}
/*
void
uvmspace_exec(struct proc *p, vaddr_t start, vaddr_t end)
{
- struct vmspace *nvm, *ovm = p->p_vmspace;
+ struct process *pr = p->p_p;
+ struct vmspace *nvm, *ovm = pr->ps_vmspace;
struct vm_map *map = &ovm->vm_map;
struct uvm_map_deadq dead_entries;
/* see if more than one process is using this vmspace... */
if (ovm->vm_refcnt == 1) {
/*
- * if p is the only process using its vmspace then we can safely
- * recycle that vmspace for the program that is being exec'd.
+ * If pr is the only process using its vmspace then
+ * we can safely recycle that vmspace for the program
+ * that is being exec'd.
*/
#ifdef SYSVSHM
pmap_remove_holes(map);
} else {
/*
- * p's vmspace is being shared, so we can't reuse it for p since
- * it is still being used for others. allocate a new vmspace
- * for p
+ * pr's vmspace is being shared, so we can't reuse
+ * it for pr since it is still being used for others.
+ * allocate a new vmspace for pr
*/
nvm = uvmspace_alloc(start, end,
(map->flags & VM_MAP_PAGEABLE) ? TRUE : FALSE, TRUE);
/* install new vmspace and drop our ref to the old one. */
pmap_deactivate(p);
- p->p_vmspace = nvm;
+ p->p_vmspace = pr->ps_vmspace = nvm;
pmap_activate(p);
uvmspace_free(ovm);
* => parent's map must not be locked.
*/
struct vmspace *
-uvmspace_fork(struct vmspace *vm1)
+uvmspace_fork(struct process *pr)
{
+ struct vmspace *vm1 = pr->ps_vmspace;
struct vmspace *vm2;
struct vm_map *old_map = &vm1->vm_map;
struct vm_map *new_map;