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