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 module rt.gc.basic.gcalloc;
27 
28 version (Win32)
29 {
30     private import tango.sys.win32.UserGdi;
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 tango.stdc.posix.sys.mman;
44     private import tango.stdc.stdlib;
45 
46     //version = GC_Use_Alloc_MMap;
47 }
48 else
49 {
50     private import tango.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     debug(PRINTF) import tango.stdc.stdio: printf;
119 
120 
121     void *os_mem_map(size_t nbytes)
122     {   void *p;
123 
124         debug(PRINTF) printf("mmap alloc of %p bytes\n", nbytes);
125         p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
126         return (p == MAP_FAILED) ? null : p;
127     }
128 
129 
130     int os_mem_commit(void *base, size_t offset, size_t nbytes)
131     {
132         return 0;
133     }
134 
135 
136     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
137     {
138         return 0;
139     }
140 
141 
142     int os_mem_unmap(void *base, size_t nbytes)
143     {
144         return munmap(base, nbytes);
145     }
146 }
147 else static if (is(typeof(valloc))) // else version (GC_Use_Alloc_Valloc)
148 {
149     void *os_mem_map(size_t nbytes)
150     {
151         return valloc(nbytes);
152     }
153 
154 
155     int os_mem_commit(void *base, size_t offset, size_t nbytes)
156     {
157         return 0;
158     }
159 
160 
161     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
162     {
163         return 0;
164     }
165 
166 
167     int os_mem_unmap(void *base, size_t nbytes)
168     {
169         free(base);
170         return 0;
171     }
172 }
173 else static if (is(typeof(malloc))) // else version (GC_Use_Alloc_Malloc)
174 {
175     // NOTE: This assumes malloc granularity is at least (void*).sizeof.  If
176     //       (req_size + PAGESIZE) is allocated, and the pointer is rounded up
177     //       to PAGESIZE alignment, there will be space for a void* at the end
178     //       after PAGESIZE bytes used by the GC.
179 
180 
181     private import rt.gc.basic.gcx; // for PAGESIZE
182 
183 
184     const size_t PAGE_MASK = PAGESIZE - 1;
185 
186 
187     void *os_mem_map(size_t nbytes)
188     {   byte *p, q;
189         p = cast(byte *) malloc(nbytes + PAGESIZE);
190         q = p + ((PAGESIZE - ((cast(size_t) p & PAGE_MASK))) & PAGE_MASK);
191         * cast(void**)(q + nbytes) = p;
192         return q;
193     }
194 
195 
196     int os_mem_commit(void *base, size_t offset, size_t nbytes)
197     {
198         return 0;
199     }
200 
201 
202     int os_mem_decommit(void *base, size_t offset, size_t nbytes)
203     {
204         return 0;
205     }
206 
207 
208     int os_mem_unmap(void *base, size_t nbytes)
209     {
210         free( *cast(void**)( cast(byte*) base + nbytes ) );
211         return 0;
212     }
213 }
214 else
215 {
216     static assert(false, "No supported allocation methods available.");
217 }