kern_descrip.c: add fdshare()/fdcopy()
kern_fork.c: add the tiny bit of code for rfork operation. kern/sysv_*: shmfork() takes one less arg, it was never used. sys/shm.h: drop "isvfork" arg from shmfork() prototype sys/param.h: declare rfork args.. (this is where OpenBSD put it..) sys/filedesc.h: protos for fdshare/fdcopy. vm/vm_mmap.c: add minherit code, add rounding to mmap() type args where it makes sense. vm/*: drop unused isvfork arg. Note: this rfork() implementation copies the address space mappings, it does not connect the mappings together. ie: once the two processes have split, the pages may be shared, but the address space is not. If one does a mmap() etc, it does not appear in the other. This makes it not useful for pthreads, but it is useful in it's own right for having light-weight threads in a static shared address space. Obtained from: Original by Ron Minnich, extended by OpenBSD
This commit is contained in:
parent
e89de7b5c3
commit
dabee6fecc
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
|
||||
* $Id: kern_descrip.c,v 1.24 1996/01/28 23:41:39 dyson Exp $
|
||||
* $Id: kern_descrip.c,v 1.25 1996/02/04 19:56:34 dyson Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -82,6 +82,7 @@ static int finishdup(struct filedesc *fdp, int old, int new, int *retval);
|
||||
*/
|
||||
struct file *filehead; /* head of list of open files */
|
||||
int nfiles; /* actual number of open files */
|
||||
extern int cmask;
|
||||
|
||||
/*
|
||||
* System calls on descriptors.
|
||||
@ -700,6 +701,49 @@ ffree(fp)
|
||||
FREE(fp, M_FILE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a new filedesc structure.
|
||||
*/
|
||||
struct filedesc *
|
||||
fdinit(p)
|
||||
struct proc *p;
|
||||
{
|
||||
register struct filedesc0 *newfdp;
|
||||
register struct filedesc *fdp = p->p_fd;
|
||||
|
||||
MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
|
||||
M_FILEDESC, M_WAITOK);
|
||||
bzero(newfdp, sizeof(struct filedesc0));
|
||||
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);
|
||||
|
||||
/* Create the file descriptor table. */
|
||||
newfdp->fd_fd.fd_refcnt = 1;
|
||||
newfdp->fd_fd.fd_cmask = cmask;
|
||||
newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
|
||||
newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
|
||||
newfdp->fd_fd.fd_nfiles = NDFILE;
|
||||
|
||||
newfdp->fd_fd.fd_freefile = 0;
|
||||
newfdp->fd_fd.fd_lastfile = 0;
|
||||
|
||||
return (&newfdp->fd_fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Share a filedesc structure.
|
||||
*/
|
||||
struct filedesc *
|
||||
fdshare(p)
|
||||
struct proc *p;
|
||||
{
|
||||
p->p_fd->fd_refcnt++;
|
||||
return (p->p_fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a filedesc structure.
|
||||
*/
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
|
||||
* $Id: kern_fork.c,v 1.15 1995/12/07 12:46:42 davidg Exp $
|
||||
* $Id: kern_fork.c,v 1.16 1996/01/03 21:42:02 wollman Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
@ -56,9 +56,17 @@
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/lock.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_extern.h>
|
||||
#include <vm/vm_inherit.h>
|
||||
|
||||
static int fork1(struct proc *, int, int *);
|
||||
static int fork1(struct proc *p, int forktype, int rforkflags, int *retval);
|
||||
|
||||
#define ISFORK 0
|
||||
#define ISVFORK 1
|
||||
#define ISRFORK 2
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct fork_args {
|
||||
@ -73,27 +81,38 @@ fork(p, uap, retval)
|
||||
struct fork_args *uap;
|
||||
int retval[];
|
||||
{
|
||||
|
||||
return (fork1(p, 0, retval));
|
||||
return (fork1(p, ISFORK, 0, retval));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
vfork(p, uap, retval)
|
||||
struct proc *p;
|
||||
struct fork_args *uap;
|
||||
struct vfork_args *uap;
|
||||
int retval[];
|
||||
{
|
||||
|
||||
return (fork1(p, 1, retval));
|
||||
return (fork1(p, ISVFORK, 0, retval));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
rfork(p, uap, retval)
|
||||
struct proc *p;
|
||||
struct rfork_args *uap;
|
||||
int retval[];
|
||||
{
|
||||
return (fork1(p, ISRFORK, uap->flags, retval));
|
||||
}
|
||||
|
||||
|
||||
int nprocs = 1; /* process 0 */
|
||||
|
||||
static int
|
||||
fork1(p1, isvfork, retval)
|
||||
fork1(p1, forktype, rforkflags, retval)
|
||||
register struct proc *p1;
|
||||
int isvfork, retval[];
|
||||
int forktype;
|
||||
int rforkflags;
|
||||
int retval[];
|
||||
{
|
||||
register struct proc *p2;
|
||||
register uid_t uid;
|
||||
@ -101,6 +120,21 @@ fork1(p1, isvfork, retval)
|
||||
struct proc **hash;
|
||||
int count;
|
||||
static int nextpid, pidchecked = 0;
|
||||
int dupfd = 1, cleanfd = 0;
|
||||
|
||||
if (forktype == ISRFORK) {
|
||||
dupfd = 0;
|
||||
if ((rforkflags & RFPROC) == 0)
|
||||
return (EINVAL);
|
||||
if ((rforkflags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
|
||||
return (EINVAL);
|
||||
if (rforkflags & RFFDG)
|
||||
dupfd = 1;
|
||||
if (rforkflags & RFNOWAIT)
|
||||
return (EINVAL); /* XXX unimplimented */
|
||||
if (rforkflags & RFCFDG)
|
||||
cleanfd = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Although process entries are dynamically created, we still keep
|
||||
@ -235,7 +269,13 @@ fork1(p1, isvfork, retval)
|
||||
if (p2->p_textvp)
|
||||
VREF(p2->p_textvp);
|
||||
|
||||
p2->p_fd = fdcopy(p1);
|
||||
if (cleanfd)
|
||||
p2->p_fd = fdinit(p1);
|
||||
else if (dupfd)
|
||||
p2->p_fd = fdcopy(p1);
|
||||
else
|
||||
p2->p_fd = fdshare(p1);
|
||||
|
||||
/*
|
||||
* If p_limit is still copy-on-write, bump refcnt,
|
||||
* otherwise get a copy that won't be modified.
|
||||
@ -251,7 +291,7 @@ fork1(p1, isvfork, retval)
|
||||
|
||||
if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
|
||||
p2->p_flag |= P_CONTROLT;
|
||||
if (isvfork)
|
||||
if (forktype == ISVFORK)
|
||||
p2->p_flag |= P_PPWAIT;
|
||||
p2->p_pgrpnxt = p1->p_pgrpnxt;
|
||||
p1->p_pgrpnxt = p2;
|
||||
@ -283,6 +323,15 @@ fork1(p1, isvfork, retval)
|
||||
*/
|
||||
p1->p_flag |= P_NOSWAP;
|
||||
|
||||
/*
|
||||
* share as much address space as possible
|
||||
*/
|
||||
if (forktype == ISRFORK && (rforkflags & RFMEM)) {
|
||||
(void) vm_map_inherit(&p1->p_vmspace->vm_map,
|
||||
VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS - MAXSSIZ,
|
||||
VM_INHERIT_SHARE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set return values for child before vm_fork,
|
||||
* so they can be copied to child stack.
|
||||
@ -293,7 +342,7 @@ fork1(p1, isvfork, retval)
|
||||
*/
|
||||
retval[0] = p1->p_pid;
|
||||
retval[1] = 1;
|
||||
if (vm_fork(p1, p2, isvfork)) {
|
||||
if (vm_fork(p1, p2)) {
|
||||
/*
|
||||
* Child process. Set start time and get to work.
|
||||
*/
|
||||
@ -321,7 +370,7 @@ fork1(p1, isvfork, retval)
|
||||
* child to exec or exit, set P_PPWAIT on child, and sleep on our
|
||||
* proc (in case of exit).
|
||||
*/
|
||||
if (isvfork)
|
||||
if (forktype == ISVFORK)
|
||||
while (p2->p_flag & P_PPWAIT)
|
||||
tsleep(p1, PWAIT, "ppwait", 0);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: sysv_ipc.c,v 1.2 1996/01/05 16:37:52 wollman Exp $ */
|
||||
/* $Id: sysv_ipc.c,v 1.3 1996/01/08 04:30:48 peter Exp $ */
|
||||
/* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */
|
||||
|
||||
/*
|
||||
@ -278,9 +278,8 @@ shmsys(p, uap, retval)
|
||||
|
||||
/* called from kern_fork.c */
|
||||
void
|
||||
shmfork(p1, p2, isvfork)
|
||||
shmfork(p1, p2)
|
||||
struct proc *p1, *p2;
|
||||
int isvfork;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: sysv_shm.c,v 1.16 1995/12/26 16:03:32 joerg Exp $ */
|
||||
/* $Id: sysv_shm.c,v 1.17 1996/01/05 16:38:03 wollman Exp $ */
|
||||
/* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */
|
||||
|
||||
/*
|
||||
@ -565,9 +565,8 @@ shmsys(p, uap, retval)
|
||||
}
|
||||
|
||||
void
|
||||
shmfork(p1, p2, isvfork)
|
||||
shmfork(p1, p2)
|
||||
struct proc *p1, *p2;
|
||||
int isvfork;
|
||||
{
|
||||
struct shmmap_state *shmmap_s;
|
||||
size_t size;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)filedesc.h 8.1 (Berkeley) 6/2/93
|
||||
* $Id: filedesc.h,v 1.6 1995/05/30 08:14:20 rgrimes Exp $
|
||||
* $Id: filedesc.h,v 1.7 1995/11/04 10:35:17 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_FILEDESC_H_
|
||||
@ -100,6 +100,8 @@ int fdalloc __P((struct proc *p, int want, int *result));
|
||||
int fdavail __P((struct proc *p, int n));
|
||||
int falloc __P((struct proc *p, struct file **resultfp, int *resultfd));
|
||||
void ffree __P((struct file *));
|
||||
struct filedesc *fdinit __P((struct proc *p));
|
||||
struct filedesc *fdshare __P((struct proc *p));
|
||||
struct filedesc *fdcopy __P((struct proc *p));
|
||||
void fdfree __P((struct proc *p));
|
||||
int closef __P((struct file *fp,struct proc *p));
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)param.h 8.2 (Berkeley) 1/21/94
|
||||
* $Id: param.h,v 1.10 1995/12/05 21:03:13 bde Exp $
|
||||
* $Id: param.h,v 1.11 1996/01/30 23:01:04 mpp Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_PARAM_H_
|
||||
@ -226,4 +226,20 @@
|
||||
#define FSHIFT 11 /* bits to right of fixed binary point */
|
||||
#define FSCALE (1<<FSHIFT)
|
||||
|
||||
/*
|
||||
* rfork() options.
|
||||
*
|
||||
* XXX currently, operations without RFPROC set are not supported.
|
||||
*/
|
||||
#define RFNAMEG (1<<0) /* UNIMPL new plan9 `name space' */
|
||||
#define RFENVG (1<<1) /* UNIMPL copy plan9 `env space' */
|
||||
#define RFFDG (1<<2) /* copy fd table */
|
||||
#define RFNOTEG (1<<3) /* UNIMPL create new plan9 `note group' */
|
||||
#define RFPROC (1<<4) /* change child (else changes curproc) */
|
||||
#define RFMEM (1<<5) /* share `address space' */
|
||||
#define RFNOWAIT (1<<6) /* UNIMPL parent need not wait() on child */
|
||||
#define RFCNAMEG (1<<10) /* UNIMPL zero plan9 `name space' */
|
||||
#define RFCENVG (1<<11) /* UNIMPL zero plan9 `env space' */
|
||||
#define RFCFDG (1<<12) /* zero fd table */
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: shm.h,v 1.6 1995/08/30 00:33:35 bde Exp $ */
|
||||
/* $Id: shm.h,v 1.7 1996/01/30 23:01:19 mpp Exp $ */
|
||||
/* $NetBSD: shm.h,v 1.15 1994/06/29 06:45:17 cgd Exp $ */
|
||||
|
||||
/*
|
||||
@ -80,7 +80,7 @@ extern struct shminfo shminfo;
|
||||
extern struct shmid_ds *shmsegs;
|
||||
|
||||
void shmexit __P((struct proc *));
|
||||
void shmfork __P((struct proc *, struct proc *, int));
|
||||
void shmfork __P((struct proc *, struct proc *));
|
||||
#else /* !KERNEL */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vm_extern.h 8.2 (Berkeley) 1/12/94
|
||||
* $Id: vm_extern.h,v 1.22 1995/12/14 09:54:55 phk Exp $
|
||||
* $Id: vm_extern.h,v 1.23 1996/02/04 22:08:57 dyson Exp $
|
||||
*/
|
||||
|
||||
#ifndef _VM_EXTERN_H_
|
||||
@ -88,7 +88,7 @@ int vm_fault __P((vm_map_t, vm_offset_t, vm_prot_t, boolean_t));
|
||||
void vm_fault_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t));
|
||||
void vm_fault_unwire __P((vm_map_t, vm_offset_t, vm_offset_t));
|
||||
int vm_fault_wire __P((vm_map_t, vm_offset_t, vm_offset_t));
|
||||
int vm_fork __P((struct proc *, struct proc *, int));
|
||||
int vm_fork __P((struct proc *, struct proc *));
|
||||
void vm_map_print __P((/* db_expr_t */ int, boolean_t, /* db_expr_t */ int, char *));
|
||||
int vm_mmap __P((vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, caddr_t, vm_ooffset_t));
|
||||
vm_offset_t vm_page_alloc_contig __P((vm_offset_t, vm_offset_t, vm_offset_t, vm_offset_t));
|
||||
|
@ -59,10 +59,9 @@
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*
|
||||
* $Id: vm_glue.c,v 1.38 1996/01/29 12:10:30 davidg Exp $
|
||||
* $Id: vm_glue.c,v 1.39 1996/02/22 10:57:36 davidg Exp $
|
||||
*/
|
||||
|
||||
#include "opt_sysvipc.h"
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -210,9 +209,8 @@ vsunlock(addr, len, dirtied)
|
||||
* after cpu_fork returns.
|
||||
*/
|
||||
int
|
||||
vm_fork(p1, p2, isvfork)
|
||||
vm_fork(p1, p2)
|
||||
register struct proc *p1, *p2;
|
||||
int isvfork;
|
||||
{
|
||||
register struct user *up;
|
||||
vm_offset_t addr, ptaddr, ptpa;
|
||||
@ -234,10 +232,8 @@ vm_fork(p1, p2, isvfork)
|
||||
UPT_MIN_ADDRESS - UPAGES * PAGE_SIZE, VM_MAX_ADDRESS, VM_INHERIT_NONE);
|
||||
p2->p_vmspace = vmspace_fork(p1->p_vmspace);
|
||||
|
||||
#ifdef SYSVSHM
|
||||
if (p1->p_vmspace->vm_shm)
|
||||
shmfork(p1, p2, isvfork);
|
||||
#endif
|
||||
shmfork(p1, p2);
|
||||
|
||||
/*
|
||||
* Allocate a wired-down (for now) pcb and kernel stack for the
|
||||
|
127
sys/vm/vm_mmap.c
127
sys/vm/vm_mmap.c
@ -38,7 +38,7 @@
|
||||
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
|
||||
*
|
||||
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
|
||||
* $Id: vm_mmap.c,v 1.34 1995/12/17 07:19:57 bde Exp $
|
||||
* $Id: vm_mmap.c,v 1.35 1996/01/19 03:59:59 dyson Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -319,7 +319,7 @@ msync(p, uap, retval)
|
||||
int *retval;
|
||||
{
|
||||
vm_offset_t addr;
|
||||
vm_size_t size;
|
||||
vm_size_t size, pageoff;
|
||||
int flags;
|
||||
vm_map_t map;
|
||||
int rv;
|
||||
@ -329,8 +329,18 @@ msync(p, uap, retval)
|
||||
size = round_page((vm_size_t) uap->len);
|
||||
flags = uap->flags;
|
||||
|
||||
if (((int) addr & PAGE_MASK) || addr + size < addr ||
|
||||
(flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE))
|
||||
/*
|
||||
* Align the address to a page boundary,
|
||||
* and adjust the size accordingly.
|
||||
*/
|
||||
pageoff = (addr & PAGE_MASK);
|
||||
addr -= pageoff;
|
||||
size += pageoff;
|
||||
size = (vm_size_t) round_page(size);
|
||||
if ((int)size < 0)
|
||||
return(EINVAL);
|
||||
|
||||
if ((flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE))
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
@ -385,15 +395,25 @@ munmap(p, uap, retval)
|
||||
int *retval;
|
||||
{
|
||||
vm_offset_t addr;
|
||||
vm_size_t size;
|
||||
vm_size_t size, pageoff;
|
||||
vm_map_t map;
|
||||
|
||||
addr = (vm_offset_t) uap->addr;
|
||||
if ((addr & PAGE_MASK) || uap->len < 0)
|
||||
return (EINVAL);
|
||||
size = (vm_size_t) round_page(uap->len);
|
||||
size = (vm_size_t) uap->len;
|
||||
|
||||
/*
|
||||
* Align the address to a page boundary,
|
||||
* and adjust the size accordingly.
|
||||
*/
|
||||
pageoff = (addr & PAGE_MASK);
|
||||
addr -= pageoff;
|
||||
size += pageoff;
|
||||
size = (vm_size_t) round_page(size);
|
||||
if ((int)size < 0)
|
||||
return(EINVAL);
|
||||
if (size == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Check for illegal addresses. Watch out for address wrap... Note
|
||||
* that VM_*_ADDRESS are not constants due to casts (argh).
|
||||
@ -442,15 +462,24 @@ mprotect(p, uap, retval)
|
||||
int *retval;
|
||||
{
|
||||
vm_offset_t addr;
|
||||
vm_size_t size;
|
||||
vm_size_t size, pageoff;
|
||||
register vm_prot_t prot;
|
||||
|
||||
addr = (vm_offset_t) uap->addr;
|
||||
if ((addr & PAGE_MASK) || uap->len < 0)
|
||||
return (EINVAL);
|
||||
size = (vm_size_t) uap->len;
|
||||
prot = uap->prot & VM_PROT_ALL;
|
||||
|
||||
/*
|
||||
* Align the address to a page boundary,
|
||||
* and adjust the size accordingly.
|
||||
*/
|
||||
pageoff = (addr & PAGE_MASK);
|
||||
addr -= pageoff;
|
||||
size += pageoff;
|
||||
size = (vm_size_t) round_page(size);
|
||||
if ((int)size < 0)
|
||||
return(EINVAL);
|
||||
|
||||
switch (vm_map_protect(&p->p_vmspace->vm_map, addr, addr + size, prot,
|
||||
FALSE)) {
|
||||
case KERN_SUCCESS:
|
||||
@ -461,6 +490,48 @@ mprotect(p, uap, retval)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct minherit_args {
|
||||
caddr_t addr;
|
||||
int len;
|
||||
int inherit;
|
||||
};
|
||||
#endif
|
||||
int
|
||||
minherit(p, uap, retval)
|
||||
struct proc *p;
|
||||
struct minherit_args *uap;
|
||||
int *retval;
|
||||
{
|
||||
vm_offset_t addr;
|
||||
vm_size_t size, pageoff;
|
||||
register vm_inherit_t inherit;
|
||||
|
||||
addr = (vm_offset_t)uap->addr;
|
||||
size = (vm_size_t)uap->len;
|
||||
inherit = uap->inherit;
|
||||
|
||||
/*
|
||||
* Align the address to a page boundary,
|
||||
* and adjust the size accordingly.
|
||||
*/
|
||||
pageoff = (addr & PAGE_MASK);
|
||||
addr -= pageoff;
|
||||
size += pageoff;
|
||||
size = (vm_size_t) round_page(size);
|
||||
if ((int)size < 0)
|
||||
return(EINVAL);
|
||||
|
||||
switch (vm_map_inherit(&p->p_vmspace->vm_map, addr, addr+size,
|
||||
inherit)) {
|
||||
case KERN_SUCCESS:
|
||||
return (0);
|
||||
case KERN_PROTECTION_FAILURE:
|
||||
return (EACCES);
|
||||
}
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct madvise_args {
|
||||
caddr_t addr;
|
||||
@ -536,13 +607,24 @@ mlock(p, uap, retval)
|
||||
int *retval;
|
||||
{
|
||||
vm_offset_t addr;
|
||||
vm_size_t size;
|
||||
vm_size_t size, pageoff;
|
||||
int error;
|
||||
|
||||
addr = (vm_offset_t) uap->addr;
|
||||
if ((addr & PAGE_MASK) || uap->addr + uap->len < uap->addr)
|
||||
size = (vm_size_t) uap->len;
|
||||
/*
|
||||
* Align the address to a page boundary,
|
||||
* and adjust the size accordingly.
|
||||
*/
|
||||
pageoff = (addr & PAGE_MASK);
|
||||
addr -= pageoff;
|
||||
size += pageoff;
|
||||
size = (vm_size_t) round_page(size);
|
||||
|
||||
/* disable wrap around */
|
||||
if (addr + (int)size < addr)
|
||||
return (EINVAL);
|
||||
size = round_page((vm_size_t) uap->len);
|
||||
|
||||
if (atop(size) + cnt.v_wire_count > vm_page_max_wired)
|
||||
return (EAGAIN);
|
||||
#ifdef pmap_wired_count
|
||||
@ -572,18 +654,29 @@ munlock(p, uap, retval)
|
||||
int *retval;
|
||||
{
|
||||
vm_offset_t addr;
|
||||
vm_size_t size;
|
||||
vm_size_t size, pageoff;
|
||||
int error;
|
||||
|
||||
addr = (vm_offset_t) uap->addr;
|
||||
if ((addr & PAGE_MASK) || uap->addr + uap->len < uap->addr)
|
||||
size = (vm_size_t) uap->len;
|
||||
/*
|
||||
* Align the address to a page boundary,
|
||||
* and adjust the size accordingly.
|
||||
*/
|
||||
pageoff = (addr & PAGE_MASK);
|
||||
addr -= pageoff;
|
||||
size += pageoff;
|
||||
size = (vm_size_t) round_page(size);
|
||||
|
||||
/* disable wrap around */
|
||||
if (addr + (int)size < addr)
|
||||
return (EINVAL);
|
||||
|
||||
#ifndef pmap_wired_count
|
||||
error = suser(p->p_ucred, &p->p_acflag);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
size = round_page((vm_size_t) uap->len);
|
||||
|
||||
error = vm_map_pageable(&p->p_vmspace->vm_map, addr, addr + size, TRUE);
|
||||
return (error == KERN_SUCCESS ? 0 : ENOMEM);
|
||||
|
Loading…
Reference in New Issue
Block a user