diff options
| author | Russ Cox <rsc@golang.org> | 2011-12-16 15:33:58 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2011-12-16 15:33:58 -0500 |
| commit | 851f30136d79c9bb752ab56d3991bb3180a5aa5b (patch) | |
| tree | d58e6051bb8e79e4d286c7b2413b25f399d90af9 /src/pkg/runtime/mem_linux.c | |
| parent | 474d64d26e8eb8d40bbe2d481513a2070d85ee54 (diff) | |
| download | go-851f30136d79c9bb752ab56d3991bb3180a5aa5b.tar.xz | |
runtime: make more build-friendly
Collapse the arch,os-specific directories into the main directory
by renaming xxx/foo.c to foo_xxx.c, and so on.
There are no substantial edits here, except to the Makefile.
The assumption is that the Go tool will #define GOOS_darwin
and GOARCH_amd64 and will make any file named something
like signals_darwin.h available as signals_GOOS.h during the
build. This replaces what used to be done with -I$(GOOS).
There is still work to be done to make runtime build with
standard tools, but this is a big step. After this we will have
to write a script to generate all the generated files so they
can be checked in (instead of generated during the build).
R=r, iant, r, lucio.dere
CC=golang-dev
https://golang.org/cl/5490053
Diffstat (limited to 'src/pkg/runtime/mem_linux.c')
| -rw-r--r-- | src/pkg/runtime/mem_linux.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/pkg/runtime/mem_linux.c b/src/pkg/runtime/mem_linux.c new file mode 100644 index 0000000000..fdf02c2cac --- /dev/null +++ b/src/pkg/runtime/mem_linux.c @@ -0,0 +1,119 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "runtime.h" +#include "arch_GOARCH.h" +#include "defs_GOOS_GOARCH.h" +#include "os_GOOS.h" +#include "malloc.h" + +enum +{ + ENOMEM = 12, + _PAGE_SIZE = 4096, +}; + +static int32 +addrspace_free(void *v, uintptr n) +{ + int32 errval; + uintptr chunk; + uintptr off; + static byte vec[4096]; + + 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) + return 0; + } + return 1; +} + + +void* +runtime·SysAlloc(uintptr n) +{ + void *p; + + mstats.sys += n; + p = runtime·mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); + if(p < (void*)4096) { + if(p == (void*)EACCES) { + runtime·printf("runtime: mmap: access denied\n"); + runtime·printf("if you're running SELinux, enable execmem for this process.\n"); + runtime·exit(2); + } + return nil; + } + return p; +} + +void +runtime·SysUnused(void *v, uintptr n) +{ + runtime·madvise(v, n, MADV_DONTNEED); +} + +void +runtime·SysFree(void *v, uintptr n) +{ + mstats.sys -= n; + runtime·munmap(v, n); +} + +void* +runtime·SysReserve(void *v, uintptr n) +{ + void *p; + + // On 64-bit, people with ulimit -v set complain if we reserve too + // much address space. Instead, assume that the reservation is okay + // and check the assumption in SysMap. + if(sizeof(void*) == 8) + return v; + + p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); + if((uintptr)p < 4096 || -(uintptr)p < 4096) { + return nil; + } + return p; +} + +void +runtime·SysMap(void *v, uintptr n) +{ + void *p; + + mstats.sys += n; + + // On 64-bit, we don't actually have v reserved, so tread carefully. + if(sizeof(void*) == 8) { + p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); + if(p != v && addrspace_free(v, n)) { + // On some systems, mmap ignores v without + // MAP_FIXED, so retry if the address space is free. + if(p > (void*)4096) { + runtime·munmap(p, n); + } + p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0); + } + if(p == (void*)ENOMEM) + runtime·throw("runtime: out of memory"); + if(p != v) { + runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p); + runtime·throw("runtime: address space conflict"); + } + return; + } + + p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0); + if(p == (void*)ENOMEM) + runtime·throw("runtime: out of memory"); + if(p != v) + runtime·throw("runtime: cannot map pages in arena address space"); +} |
