summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2010-10-21 17:29:32 +0000
committerjhb <jhb@FreeBSD.org>2010-10-21 17:29:32 +0000
commit2d6ab8853a286164be8e70da0268b3599ccaa0d3 (patch)
treecf57ca3486d101a83bf6249dd02ff5ba997700e7 /sys/vm
parent24f2e3e95977a97fcfdb49f610bab77d3e6fceb9 (diff)
downloadFreeBSD-src-2d6ab8853a286164be8e70da0268b3599ccaa0d3.zip
FreeBSD-src-2d6ab8853a286164be8e70da0268b3599ccaa0d3.tar.gz
- Make 'vm_refcnt' volatile so that compilers won't be tempted to treat
its value as a loop invariant. Currently this is a no-op because 'atomic_cmpset_int()' clobbers all memory on current architectures. - Use atomic_fetchadd_int() instead of an atomic_cmpset_int() loop to drop a reference in vmspace_free(). Reviewed by: alc MFC after: 1 month
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_map.c6
-rw-r--r--sys/vm/vm_map.h2
2 files changed, 2 insertions, 6 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 2e0f001..40c317d 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -339,15 +339,11 @@ vmspace_dofree(struct vmspace *vm)
void
vmspace_free(struct vmspace *vm)
{
- int refcnt;
if (vm->vm_refcnt == 0)
panic("vmspace_free: attempt to free already freed vmspace");
- do
- refcnt = vm->vm_refcnt;
- while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt - 1));
- if (refcnt == 1)
+ if (atomic_fetchadd_int(&vm->vm_refcnt, -1) == 1)
vmspace_dofree(vm);
}
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index 18a1edf..8715b41 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -236,7 +236,7 @@ struct vmspace {
caddr_t vm_taddr; /* (c) user virtual address of text */
caddr_t vm_daddr; /* (c) user virtual address of data */
caddr_t vm_maxsaddr; /* user VA at max stack growth */
- int vm_refcnt; /* number of references */
+ volatile int vm_refcnt; /* number of references */
/*
* Keep the PMAP last, so that CPU-specific variations of that
* structure on a single architecture don't result in offset
OpenPOWER on IntegriCloud