]> git.llucax.com Git - software/druntime.git/blob - src/gc/basic/gcalloc.d
Allow building directly using 'make'
[software/druntime.git] / src / gc / basic / gcalloc.d
1 /**
2  * This module contains allocation functions for the garbage collector.
3  *
4  * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com.
5  *            All rights reserved.
6  * License:
7  *  This software is provided 'as-is', without any express or implied
8  *  warranty. In no event will the authors be held liable for any damages
9  *  arising from the use of this software.
10  *
11  *  Permission is granted to anyone to use this software for any purpose,
12  *  including commercial applications, and to alter it and redistribute it
13  *  freely, in both source and binary form, subject to the following
14  *  restrictions:
15  *
16  *  o  The origin of this software must not be misrepresented; you must not
17  *     claim that you wrote the original software. If you use this software
18  *     in a product, an acknowledgment in the product documentation would be
19  *     appreciated but is not required.
20  *  o  Altered source versions must be plainly marked as such, and must not
21  *     be misrepresented as being the original software.
22  *  o  This notice may not be removed or altered from any source
23  *     distribution.
24  * Authors:   Walter Bright, David Friedman, Sean Kelly
25  */
26
27 module gc.gcalloc;
28
29
30 version (Windows)
31 {
32     private import core.sys.windows.windows;
33
34     alias int pthread_t;
35
36     pthread_t pthread_self()
37     {
38         return cast(pthread_t) GetCurrentThreadId();
39     }
40
41     //version = GC_Use_Alloc_Win32;
42 }
43 else version (Posix)
44 {
45     private import core.sys.posix.sys.mman;
46     private import core.stdc.stdlib;
47
48     //version = GC_Use_Alloc_MMap;
49 }
50 else
51 {
52     private import core.stdc.stdlib;
53
54     //version = GC_Use_Alloc_Malloc;
55 }
56
57 /+
58 static if(is(typeof(VirtualAlloc)))
59     version = GC_Use_Alloc_Win32;
60 else static if (is(typeof(mmap)))
61     version = GC_Use_Alloc_MMap;
62 else static if (is(typeof(valloc)))
63     version = GC_Use_Alloc_Valloc;
64 else static if (is(typeof(malloc)))
65     version = GC_Use_Alloc_Malloc;
66 else static assert(false, "No supported allocation methods available.");
67 +/
68
69 static if (is(typeof(VirtualAlloc))) // version (GC_Use_Alloc_Win32)
70 {
71     /**
72      * Map memory.
73      */
74     void *os_mem_map(size_t nbytes)
75     {
76         return VirtualAlloc(null, nbytes, MEM_RESERVE, PAGE_READWRITE);
77     }
78
79
80     /**
81      * Commit memory.
82      * Returns:
83      *      0       success
84      *      !=0     failure
85      */
86     int os_mem_commit(void *base, size_t offset, size_t nbytes)
87     {   void *p;
88
89         p = VirtualAlloc(base + offset, nbytes, MEM_COMMIT, PAGE_READWRITE);
90     return cast(int)(p is null);
91     }
92
93
94     /**
95      * Decommit memory.
96      * Returns:
97      *      0       success
98      *      !=0     failure
99      */
100     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
101     {
102     return cast(int)(VirtualFree(base + offset, nbytes, MEM_DECOMMIT) == 0);
103     }
104
105
106     /**
107      * Unmap memory allocated with os_mem_map().
108      * Memory must have already been decommitted.
109      * Returns:
110      *      0       success
111      *      !=0     failure
112      */
113     int os_mem_unmap(void *base, size_t nbytes)
114     {
115         return cast(int)(VirtualFree(base, 0, MEM_RELEASE) == 0);
116     }
117 }
118 else static if (is(typeof(mmap)))  // else version (GC_Use_Alloc_MMap)
119 {
120     void *os_mem_map(size_t nbytes)
121     {   void *p;
122
123         p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
124         return (p == MAP_FAILED) ? null : p;
125     }
126
127
128     int os_mem_commit(void *base, size_t offset, size_t nbytes)
129     {
130         return 0;
131     }
132
133
134     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
135     {
136         return 0;
137     }
138
139
140     int os_mem_unmap(void *base, size_t nbytes)
141     {
142         return munmap(base, nbytes);
143     }
144 }
145 else static if (is(typeof(valloc))) // else version (GC_Use_Alloc_Valloc)
146 {
147     void *os_mem_map(size_t nbytes)
148     {
149         return valloc(nbytes);
150     }
151
152
153     int os_mem_commit(void *base, size_t offset, size_t nbytes)
154     {
155         return 0;
156     }
157
158
159     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
160     {
161         return 0;
162     }
163
164
165     int os_mem_unmap(void *base, size_t nbytes)
166     {
167         free(base);
168         return 0;
169     }
170 }
171 else static if (is(typeof(malloc))) // else version (GC_Use_Alloc_Malloc)
172 {
173     // NOTE: This assumes malloc granularity is at least (void*).sizeof.  If
174     //       (req_size + PAGESIZE) is allocated, and the pointer is rounded up
175     //       to PAGESIZE alignment, there will be space for a void* at the end
176     //       after PAGESIZE bytes used by the GC.
177
178
179     private import gcx : PAGESIZE;
180
181
182     const size_t PAGE_MASK = PAGESIZE - 1;
183
184
185     void *os_mem_map(size_t nbytes)
186     {   byte *p, q;
187         p = cast(byte *) malloc(nbytes + PAGESIZE);
188         q = p + ((PAGESIZE - ((cast(size_t) p & PAGE_MASK))) & PAGE_MASK);
189         * cast(void**)(q + nbytes) = p;
190         return q;
191     }
192
193
194     int os_mem_commit(void *base, size_t offset, size_t nbytes)
195     {
196         return 0;
197     }
198
199
200     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
201     {
202         return 0;
203     }
204
205
206     int os_mem_unmap(void *base, size_t nbytes)
207     {
208         free( *cast(void**)( cast(byte*) base + nbytes ) );
209         return 0;
210     }
211 }
212 else
213 {
214     static assert(false, "No supported allocation methods available.");
215 }