summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_map.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-07-27 03:53:41 +0000
committeralc <alc@FreeBSD.org>2004-07-27 03:53:41 +0000
commit8a38bc6b2ce7980dbddef0dc33bfba51ec5d3824 (patch)
tree6d7127f6cedfdcd82a7c1768b6c913502023d8cf /sys/vm/vm_map.c
parenta745685147cf8bdd139918b29529822fc40acdf6 (diff)
downloadFreeBSD-src-8a38bc6b2ce7980dbddef0dc33bfba51ec5d3824.zip
FreeBSD-src-8a38bc6b2ce7980dbddef0dc33bfba51ec5d3824.tar.gz
- Use atomic ops for updating the vmspace's refcnt and exitingcnt.
- Push down Giant into shmexit(). (Giant is acquired only if the vmspace contains shm segments.) - Eliminate the acquisition of Giant from proc_rwmem(). - Reduce the scope of Giant in exit1(), uncovering the destruction of the address space.
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r--sys/vm/vm_map.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 3585b8a..cbeb906 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -311,13 +311,15 @@ vmspace_dofree(struct vmspace *vm)
void
vmspace_free(struct vmspace *vm)
{
- GIANT_REQUIRED;
+ int refcnt;
if (vm->vm_refcnt == 0)
panic("vmspace_free: attempt to free already freed vmspace");
- --vm->vm_refcnt;
- if (vm->vm_refcnt == 0 && vm->vm_exitingcnt == 0)
+ do
+ refcnt = vm->vm_refcnt;
+ while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt - 1));
+ if (refcnt == 1 && vm->vm_exitingcnt == 0)
vmspace_dofree(vm);
}
@@ -325,8 +327,8 @@ void
vmspace_exitfree(struct proc *p)
{
struct vmspace *vm;
+ int exitingcnt;
- GIANT_REQUIRED;
vm = p->p_vmspace;
p->p_vmspace = NULL;
@@ -341,8 +343,11 @@ vmspace_exitfree(struct proc *p)
* The last wait on the exiting child's vmspace will clean up
* the remainder of the vmspace.
*/
- --vm->vm_exitingcnt;
- if (vm->vm_refcnt == 0 && vm->vm_exitingcnt == 0)
+ do
+ exitingcnt = vm->vm_exitingcnt;
+ while (!atomic_cmpset_int(&vm->vm_exitingcnt, exitingcnt,
+ exitingcnt - 1));
+ if (vm->vm_refcnt == 0 && exitingcnt == 1)
vmspace_dofree(vm);
}
OpenPOWER on IntegriCloud