]> git.llucax.com Git - software/dgc/cdgc.git/blob - gc/alloc.d
cad30f2cd62faed18e7eabd52d15666ecd0e610e
[software/dgc/cdgc.git] / gc / alloc.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.alloc;
28
29 version (Win32)
30 {
31     import tango.sys.win32.UserGdi;
32
33     alias int pthread_t;
34
35     pthread_t pthread_self()
36     {
37         return cast(pthread_t) GetCurrentThreadId();
38     }
39
40     //version = GC_Use_Alloc_Win32;
41 }
42 else version (Posix)
43 {
44     import tango.stdc.posix.sys.mman;
45     import tango.stdc.stdlib;
46
47     //version = GC_Use_Alloc_MMap;
48 }
49 else
50 {
51     import tango.stdc.stdlib;
52
53     //version = GC_Use_Alloc_Malloc;
54 }
55
56 /+
57 static if(is(typeof(VirtualAlloc)))
58     version = GC_Use_Alloc_Win32;
59 else static if (is(typeof(mmap)))
60     version = GC_Use_Alloc_MMap;
61 else static if (is(typeof(valloc)))
62     version = GC_Use_Alloc_Valloc;
63 else static if (is(typeof(malloc)))
64     version = GC_Use_Alloc_Malloc;
65 else static assert(false, "No supported allocation methods available.");
66 +/
67
68 static if (is(typeof(VirtualAlloc))) // version (GC_Use_Alloc_Win32)
69 {
70     /**
71      * Map memory.
72      */
73     void *os_mem_map(size_t nbytes)
74     {
75         return VirtualAlloc(null, nbytes, MEM_RESERVE, PAGE_READWRITE);
76     }
77
78
79     /**
80      * Commit memory.
81      * Returns:
82      *      0       success
83      *      !=0     failure
84      */
85     int os_mem_commit(void *base, size_t offset, size_t nbytes)
86     {   void *p;
87
88         p = VirtualAlloc(base + offset, nbytes, MEM_COMMIT, PAGE_READWRITE);
89     return cast(int)(p is null);
90     }
91
92
93     /**
94      * Decommit memory.
95      * Returns:
96      *      0       success
97      *      !=0     failure
98      */
99     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
100     {
101     return cast(int)(VirtualFree(base + offset, nbytes, MEM_DECOMMIT) == 0);
102     }
103
104
105     /**
106      * Unmap memory allocated with os_mem_map().
107      * Memory must have already been decommitted.
108      * Returns:
109      *      0       success
110      *      !=0     failure
111      */
112     int os_mem_unmap(void *base, size_t nbytes)
113     {
114         return cast(int)(VirtualFree(base, 0, MEM_RELEASE) == 0);
115     }
116 }
117 else static if (is(typeof(mmap)))  // else version (GC_Use_Alloc_MMap)
118 {
119     void *os_mem_map(size_t nbytes)
120     {   void *p;
121
122         p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
123         return (p == MAP_FAILED) ? null : p;
124     }
125
126
127     int os_mem_commit(void *base, size_t offset, size_t nbytes)
128     {
129         return 0;
130     }
131
132
133     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
134     {
135         return 0;
136     }
137
138
139     int os_mem_unmap(void *base, size_t nbytes)
140     {
141         return munmap(base, nbytes);
142     }
143 }
144 else static if (is(typeof(valloc))) // else version (GC_Use_Alloc_Valloc)
145 {
146     void *os_mem_map(size_t nbytes)
147     {
148         return valloc(nbytes);
149     }
150
151
152     int os_mem_commit(void *base, size_t offset, size_t nbytes)
153     {
154         return 0;
155     }
156
157
158     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
159     {
160         return 0;
161     }
162
163
164     int os_mem_unmap(void *base, size_t nbytes)
165     {
166         free(base);
167         return 0;
168     }
169 }
170 else static if (is(typeof(malloc))) // else version (GC_Use_Alloc_Malloc)
171 {
172     // NOTE: This assumes malloc granularity is at least (void*).sizeof.  If
173     //       (req_size + PAGESIZE) is allocated, and the pointer is rounded up
174     //       to PAGESIZE alignment, there will be space for a void* at the end
175     //       after PAGESIZE bytes used by the GC.
176
177
178     import gcx; // for PAGESIZE
179
180
181     const size_t PAGE_MASK = PAGESIZE - 1;
182
183
184     void *os_mem_map(size_t nbytes)
185     {   byte *p, q;
186         p = cast(byte *) malloc(nbytes + PAGESIZE);
187         q = p + ((PAGESIZE - ((cast(size_t) p & PAGE_MASK))) & PAGE_MASK);
188         * cast(void**)(q + nbytes) = p;
189         return q;
190     }
191
192
193     int os_mem_commit(void *base, size_t offset, size_t nbytes)
194     {
195         return 0;
196     }
197
198
199     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
200     {
201         return 0;
202     }
203
204
205     int os_mem_unmap(void *base, size_t nbytes)
206     {
207         free( *cast(void**)( cast(byte*) base + nbytes ) );
208         return 0;
209     }
210 }
211 else
212 {
213     static assert(false, "No supported allocation methods available.");
214 }