|
|
| version 1.22, 2004/03/01 06:33:24 | version 1.23, 2004/03/12 23:09:37 |
|---|---|
| Line 2632 vmspace_fork(struct vmspace *vm1) | Line 2632 vmspace_fork(struct vmspace *vm1) |
| vm_map_lock(old_map); | vm_map_lock(old_map); |
| old_map->infork = 1; | old_map->infork = 1; |
| /* | |
| * XXX Note: upcalls are not copied. | |
| */ | |
| vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset); | vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset); |
| bcopy(&vm1->vm_startcopy, &vm2->vm_startcopy, | bcopy(&vm1->vm_startcopy, &vm2->vm_startcopy, |
| (caddr_t) (vm1 + 1) - (caddr_t) &vm1->vm_startcopy); | (caddr_t)&vm1->vm_endcopy - (caddr_t)&vm1->vm_startcopy); |
| new_map = &vm2->vm_map; /* XXX */ | new_map = &vm2->vm_map; /* XXX */ |
| new_map->timestamp = 1; | new_map->timestamp = 1; |
| Line 2990 vmspace_exec(struct proc *p, struct vmsp | Line 2993 vmspace_exec(struct proc *p, struct vmsp |
| /* | /* |
| * If we are execing a resident vmspace we fork it, otherwise | * If we are execing a resident vmspace we fork it, otherwise |
| * we create a new vmspace. | * we create a new vmspace. Note that exitingcnt and upcalls |
| * are not copied to the new vmspace. | |
| */ | */ |
| if (vmcopy) { | if (vmcopy) { |
| newvmspace = vmspace_fork(vmcopy); | newvmspace = vmspace_fork(vmcopy); |
| } else { | } else { |
| newvmspace = vmspace_alloc(map->min_offset, map->max_offset); | newvmspace = vmspace_alloc(map->min_offset, map->max_offset); |
| bcopy(&oldvmspace->vm_startcopy, &newvmspace->vm_startcopy, | bcopy(&oldvmspace->vm_startcopy, &newvmspace->vm_startcopy, |
| (caddr_t)(newvmspace+1) - (caddr_t) &newvmspace->vm_startcopy); | (caddr_t)&oldvmspace->vm_endcopy - |
| (caddr_t)&oldvmspace->vm_startcopy); | |
| } | } |
| /* | /* |
| Line 3017 vmspace_exec(struct proc *p, struct vmsp | Line 3022 vmspace_exec(struct proc *p, struct vmsp |
| /* | /* |
| * Unshare the specified VM space for forcing COW. This | * Unshare the specified VM space for forcing COW. This |
| * is called by rfork, for the (RFMEM|RFPROC) == 0 case. | * is called by rfork, for the (RFMEM|RFPROC) == 0 case. |
| * | |
| * The exitingcnt test is not strictly necessary but has been | |
| * included for code sanity (to make the code a bit more deterministic). | |
| */ | */ |
| void | void |
| Line 3025 vmspace_unshare(struct proc *p) | Line 3033 vmspace_unshare(struct proc *p) |
| struct vmspace *oldvmspace = p->p_vmspace; | struct vmspace *oldvmspace = p->p_vmspace; |
| struct vmspace *newvmspace; | struct vmspace *newvmspace; |
| if (oldvmspace->vm_refcnt == 1) | if (oldvmspace->vm_refcnt == 1 && oldvmspace->vm_exitingcnt == 0) |
| return; | return; |
| newvmspace = vmspace_fork(oldvmspace); | newvmspace = vmspace_fork(oldvmspace); |
| p->p_vmspace = newvmspace; | p->p_vmspace = newvmspace; |