OSDN Git Service

Update to current version of Go library.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / mem.c
1 #include <errno.h>
2
3 #include "runtime.h"
4 #include "malloc.h"
5
6 #ifndef MAP_ANON
7 #ifdef MAP_ANONYMOUS
8 #define MAP_ANON MAP_ANONYMOUS
9 #else
10 #define USE_DEV_ZERO
11 #define MAP_ANON 0
12 #endif
13 #endif
14
15 #ifdef USE_DEV_ZERO
16 static int dev_zero = -1;
17 #endif
18
19 void*
20 runtime_SysAlloc(uintptr n)
21 {
22         void *p;
23         int fd = -1;
24
25         mstats.sys += n;
26
27 #ifdef USE_DEV_ZERO
28         if (dev_zero == -1) {
29                 dev_zero = open("/dev/zero", O_RDONLY);
30                 if (dev_zero < 0) {
31                         printf("open /dev/zero: errno=%d\n", errno);
32                         exit(2);
33                 }
34         }
35         fd = dev_zero;
36 #endif
37
38         p = runtime_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0);
39         if (p == MAP_FAILED) {
40                 if(errno == EACCES) {
41                         printf("runtime: mmap: access denied\n");
42                         printf("if you're running SELinux, enable execmem for this process.\n");
43                         exit(2);
44                 }
45                 return nil;
46         }
47         return p;
48 }
49
50 void
51 runtime_SysUnused(void *v, uintptr n)
52 {
53         USED(v);
54         USED(n);
55         // TODO(rsc): call madvise MADV_DONTNEED
56 }
57
58 void
59 runtime_SysFree(void *v, uintptr n)
60 {
61         mstats.sys -= n;
62         runtime_munmap(v, n);
63 }
64
65 void*
66 runtime_SysReserve(void *v, uintptr n)
67 {
68         int fd = -1;
69
70         // On 64-bit, people with ulimit -v set complain if we reserve too
71         // much address space.  Instead, assume that the reservation is okay
72         // and check the assumption in SysMap.
73         if(sizeof(void*) == 8)
74                 return v;
75         
76 #ifdef USE_DEV_ZERO
77         if (dev_zero == -1) {
78                 dev_zero = open("/dev/zero", O_RDONLY);
79                 if (dev_zero < 0) {
80                         printf("open /dev/zero: errno=%d\n", errno);
81                         exit(2);
82                 }
83         }
84         fd = dev_zero;
85 #endif
86
87         return runtime_mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, fd, 0);
88 }
89
90 void
91 runtime_SysMap(void *v, uintptr n)
92 {
93         void *p;
94         int fd = -1;
95         
96         mstats.sys += n;
97
98 #ifdef USE_DEV_ZERO
99         if (dev_zero == -1) {
100                 dev_zero = open("/dev/zero", O_RDONLY);
101                 if (dev_zero < 0) {
102                         printf("open /dev/zero: errno=%d\n", errno);
103                         exit(2);
104                 }
105         }
106         fd = dev_zero;
107 #endif
108
109         // On 64-bit, we don't actually have v reserved, so tread carefully.
110         if(sizeof(void*) == 8) {
111                 p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, fd, 0);
112                 if(p != v) {
113                         runtime_printf("runtime: address space conflict: map(%p) = %p\n", v, p);
114                         runtime_throw("runtime: address space conflict");
115                 }
116                 return;
117         }
118
119         p = runtime_mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, fd, 0);
120         if(p != v)
121                 runtime_throw("runtime: cannot map pages in arena address space");
122 }