diff options
author | alc <alc@FreeBSD.org> | 2004-07-27 03:53:41 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-07-27 03:53:41 +0000 |
commit | 8a38bc6b2ce7980dbddef0dc33bfba51ec5d3824 (patch) | |
tree | 6d7127f6cedfdcd82a7c1768b6c913502023d8cf /sys/kern/kern_exit.c | |
parent | a745685147cf8bdd139918b29529822fc40acdf6 (diff) | |
download | FreeBSD-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/kern/kern_exit.c')
-rw-r--r-- | sys/kern/kern_exit.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a268771..78f3feb 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -114,6 +114,7 @@ exit1(struct thread *td, int rv) struct ucred *tracecred; #endif struct plimit *plim; + int refcnt; /* * Drop Giant if caller has it. Eventually we should warn about @@ -254,7 +255,6 @@ retry: } mtx_unlock(&ppeers_lock); - mtx_lock(&Giant); /* The next two chunks should probably be moved to vmspace_exit. */ vm = p->p_vmspace; /* @@ -272,8 +272,11 @@ retry: * by vmspace_exit() (which decrements exitingcnt) cleans up the * remainder. */ - ++vm->vm_exitingcnt; - if (--vm->vm_refcnt == 0) { + atomic_add_int(&vm->vm_exitingcnt, 1); + do + refcnt = vm->vm_refcnt; + while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt - 1)); + if (refcnt == 1) { shmexit(vm); pmap_remove_pages(vmspace_pmap(vm), vm_map_min(&vm->vm_map), vm_map_max(&vm->vm_map)); @@ -281,6 +284,7 @@ retry: vm_map_max(&vm->vm_map)); } + mtx_lock(&Giant); sx_xlock(&proctree_lock); if (SESS_LEADER(p)) { struct session *sp; |