1 /*
2  * Distributed under the Boost Software License, Version 1.0.
3  *    (See accompanying file LICENSE_1_0.txt or copy at
4  *          http://www.boost.org/LICENSE_1_0.txt)
5  */
6 module glib.gmem;
7 
8 import glib.gtypes;
9 
10 
11 
12 static if(GLIB_SIZEOF_VOID_P > GLIB_SIZEOF_LONG)
13 {
14     enum G_MEM_ALIGN = GLIB_SIZEOF_VOID_P;
15 }
16 else {
17     enum G_MEM_ALIGN = GLIB_SIZEOF_LONG;
18 }
19 
20 
21 extern (C) {
22 
23     void	 g_free	          (gpointer	 mem);
24 
25 
26     void     g_clear_pointer  (gpointer      *pp,
27                                GDestroyNotify destroy);
28 
29 
30     gpointer g_malloc         (gsize	 n_bytes);
31 
32     gpointer g_malloc0        (gsize	 n_bytes);
33 
34     gpointer g_realloc        (gpointer	 mem,
35                    gsize	 n_bytes);
36 
37     gpointer g_try_malloc     (gsize	 n_bytes);
38 
39     gpointer g_try_malloc0    (gsize	 n_bytes);
40 
41     gpointer g_try_realloc    (gpointer	 mem,
42                    gsize	 n_bytes);
43 
44 
45     gpointer g_malloc_n       (gsize	 n_blocks,
46                    gsize	 n_block_bytes);
47 
48     gpointer g_malloc0_n      (gsize	 n_blocks,
49                    gsize	 n_block_bytes);
50 
51     gpointer g_realloc_n      (gpointer	 mem,
52                    gsize	 n_blocks,
53                    gsize	 n_block_bytes);
54 
55     gpointer g_try_malloc_n   (gsize	 n_blocks,
56                    gsize	 n_block_bytes);
57 
58     gpointer g_try_malloc0_n  (gsize	 n_blocks,
59                    gsize	 n_block_bytes);
60 
61     gpointer g_try_realloc_n  (gpointer	 mem,
62                    gsize	 n_blocks,
63                    gsize	 n_block_bytes);
64 }
65 
66 
67 // TODO: impl or translate following macros in D
68 
69 // #define g_clear_pointer(pp, destroy) \
70 //   G_STMT_START {                                                               \
71 //     G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer));                       \
72 //     /* Only one access, please */                                              \
73 //     gpointer *_pp = (gpointer *) (pp);                                         \
74 //     gpointer _p;                                                               \
75 //     /* This assignment is needed to avoid a gcc warning */                     \
76 //     GDestroyNotify _destroy = (GDestroyNotify) (destroy);                      \
77 //                                                                                \
78 //     _p = *_pp;                                                                 \
79 //     if (_p) 								       \
80 //       { 								       \
81 //         *_pp = NULL;							       \
82 //         _destroy (_p);                                                         \
83 //       }                                                                        \
84 //   } G_STMT_END
85 
86 /* Optimise: avoid the call to the (slower) _n function if we can
87  * determine at compile-time that no overflow happens.
88  */
89 // #if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__)
90 // #  define _G_NEW(struct_type, n_structs, func) \
91 // 	(struct_type *) (G_GNUC_EXTENSION ({			\
92 // 	  gsize __n = (gsize) (n_structs);			\
93 // 	  gsize __s = sizeof (struct_type);			\
94 // 	  gpointer __p;						\
95 // 	  if (__s == 1)						\
96 // 	    __p = g_##func (__n);				\
97 // 	  else if (__builtin_constant_p (__n) &&		\
98 // 	           (__s == 0 || __n <= G_MAXSIZE / __s))	\
99 // 	    __p = g_##func (__n * __s);				\
100 // 	  else							\
101 // 	    __p = g_##func##_n (__n, __s);			\
102 // 	  __p;							\
103 // 	}))
104 // #  define _G_RENEW(struct_type, mem, n_structs, func) \
105 // 	(struct_type *) (G_GNUC_EXTENSION ({			\
106 // 	  gsize __n = (gsize) (n_structs);			\
107 // 	  gsize __s = sizeof (struct_type);			\
108 // 	  gpointer __p = (gpointer) (mem);			\
109 // 	  if (__s == 1)						\
110 // 	    __p = g_##func (__p, __n);				\
111 // 	  else if (__builtin_constant_p (__n) &&		\
112 // 	           (__s == 0 || __n <= G_MAXSIZE / __s))	\
113 // 	    __p = g_##func (__p, __n * __s);			\
114 // 	  else							\
115 // 	    __p = g_##func##_n (__p, __n, __s);			\
116 // 	  __p;							\
117 // 	}))
118 //
119 // #else
120 
121 /* Unoptimised version: always call the _n() function. */
122 
123 // #define _G_NEW(struct_type, n_structs, func) \
124 //         ((struct_type *) g_##func##_n ((n_structs), sizeof (struct_type)))
125 // #define _G_RENEW(struct_type, mem, n_structs, func) \
126 //         ((struct_type *) g_##func##_n (mem, (n_structs), sizeof (struct_type)))
127 //
128 // #endif
129 
130 /**
131  * g_new:
132  * @struct_type: the type of the elements to allocate
133  * @n_structs: the number of elements to allocate
134  *
135  * Allocates @n_structs elements of type @struct_type.
136  * The returned pointer is cast to a pointer to the given type.
137  * If @n_structs is 0 it returns %NULL.
138  * Care is taken to avoid overflow when calculating the size of the allocated block.
139  *
140  * Since the returned pointer is already casted to the right type,
141  * it is normally unnecessary to cast it explicitly, and doing
142  * so might hide memory allocation errors.
143  *
144  * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type
145  */
146 // #define g_new(struct_type, n_structs)			_G_NEW (struct_type, n_structs, malloc)
147 /**
148  * g_new0:
149  * @struct_type: the type of the elements to allocate.
150  * @n_structs: the number of elements to allocate.
151  *
152  * Allocates @n_structs elements of type @struct_type, initialized to 0's.
153  * The returned pointer is cast to a pointer to the given type.
154  * If @n_structs is 0 it returns %NULL.
155  * Care is taken to avoid overflow when calculating the size of the allocated block.
156  *
157  * Since the returned pointer is already casted to the right type,
158  * it is normally unnecessary to cast it explicitly, and doing
159  * so might hide memory allocation errors.
160  *
161  * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type.
162  */
163 //#define g_new0(struct_type, n_structs)			_G_NEW (struct_type, n_structs, malloc0)
164 /**
165  * g_renew:
166  * @struct_type: the type of the elements to allocate
167  * @mem: the currently allocated memory
168  * @n_structs: the number of elements to allocate
169  *
170  * Reallocates the memory pointed to by @mem, so that it now has space for
171  * @n_structs elements of type @struct_type. It returns the new address of
172  * the memory, which may have been moved.
173  * Care is taken to avoid overflow when calculating the size of the allocated block.
174  *
175  * Returns: a pointer to the new allocated memory, cast to a pointer to @struct_type
176  */
177 //#define g_renew(struct_type, mem, n_structs)		_G_RENEW (struct_type, mem, n_structs, realloc)
178 /**
179  * g_try_new:
180  * @struct_type: the type of the elements to allocate
181  * @n_structs: the number of elements to allocate
182  *
183  * Attempts to allocate @n_structs elements of type @struct_type, and returns
184  * %NULL on failure. Contrast with g_new(), which aborts the program on failure.
185  * The returned pointer is cast to a pointer to the given type.
186  * The function returns %NULL when @n_structs is 0 of if an overflow occurs.
187  *
188  * Since: 2.8
189  * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type
190  */
191 //#define g_try_new(struct_type, n_structs)		_G_NEW (struct_type, n_structs, try_malloc)
192 /**
193  * g_try_new0:
194  * @struct_type: the type of the elements to allocate
195  * @n_structs: the number of elements to allocate
196  *
197  * Attempts to allocate @n_structs elements of type @struct_type, initialized
198  * to 0's, and returns %NULL on failure. Contrast with g_new0(), which aborts
199  * the program on failure.
200  * The returned pointer is cast to a pointer to the given type.
201  * The function returns %NULL when @n_structs is 0 of if an overflow occurs.
202  *
203  * Since: 2.8
204  * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type
205  */
206 //#define g_try_new0(struct_type, n_structs)		_G_NEW (struct_type, n_structs, try_malloc0)
207 /**
208  * g_try_renew:
209  * @struct_type: the type of the elements to allocate
210  * @mem: the currently allocated memory
211  * @n_structs: the number of elements to allocate
212  *
213  * Attempts to reallocate the memory pointed to by @mem, so that it now has
214  * space for @n_structs elements of type @struct_type, and returns %NULL on
215  * failure. Contrast with g_renew(), which aborts the program on failure.
216  * It returns the new address of the memory, which may have been moved.
217  * The function returns %NULL if an overflow occurs.
218  *
219  * Since: 2.8
220  * Returns: a pointer to the new allocated memory, cast to a pointer to @struct_type
221  */
222 //#define g_try_renew(struct_type, mem, n_structs)	_G_RENEW (struct_type, mem, n_structs, try_realloc)
223 
224 
225 extern (C) {
226 
227     struct GMemVTable {
228 
229         gpointer function (gsize n_bytes) malloc;
230         gpointer function (gpointer mem, gsize n_bytes) realloc;
231         gpointer function (gpointer mem) free;
232 
233         gpointer function (gsize n_blocks, gsize n_block_bytes) calloc;
234         gpointer function (gsize n_bytes) try_malloc;
235         gpointer function (gpointer mem, gsize n_bytes) try_realloc;
236 
237     }
238 
239     void	 g_mem_set_vtable (GMemVTable	*vtable);
240 
241     gboolean g_mem_is_system_malloc ();
242 
243     extern __gshared gboolean g_mem_gc_friendly;
244 
245     extern __gshared GMemVTable	*glib_mem_profiler_table;
246 
247     void	g_mem_profile	();
248 
249 }
250