aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-04-03 19:04:47 -0400
committerRuss Cox <rsc@golang.org>2014-04-03 19:04:47 -0400
commit0e1b6bb5470701090cd8dadacc6eb5074a86cf82 (patch)
treec96c5a2770f55b79eb94a8e09501ee114cd7267b /src/pkg/runtime
parentf3ecb298ad3187a6c47f43916480d396ec8c35c3 (diff)
downloadgo-0e1b6bb5470701090cd8dadacc6eb5074a86cf82.tar.xz
runtime: use mincore correctly in addrspace_free
Fixes #7476. LGTM=iant R=iant CC=golang-codereviews https://golang.org/cl/84000043
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/mem_linux.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/pkg/runtime/mem_linux.c b/src/pkg/runtime/mem_linux.c
index 3f997be96b..635594c365 100644
--- a/src/pkg/runtime/mem_linux.c
+++ b/src/pkg/runtime/mem_linux.c
@@ -20,15 +20,22 @@ addrspace_free(void *v, uintptr n)
int32 errval;
uintptr chunk;
uintptr off;
- static byte vec[4096];
+
+ // NOTE: vec must be just 1 byte long here.
+ // Mincore returns ENOMEM if any of the pages are unmapped,
+ // but we want to know that all of the pages are unmapped.
+ // To make these the same, we can only ask about one page
+ // at a time. See golang.org/issue/7476.
+ static byte vec[1];
for(off = 0; off < n; off += chunk) {
chunk = _PAGE_SIZE * sizeof vec;
if(chunk > (n - off))
chunk = n - off;
errval = runtime·mincore((int8*)v + off, chunk, vec);
- // errval is 0 if success, or -(error_code) if error.
- if (errval == 0 || errval != -ENOMEM)
+ // ENOMEM means unmapped, which is what we want.
+ // Anything else we assume means the pages are mapped.
+ if (errval != -ENOMEM)
return 0;
}
return 1;