Clean Glib header #include issues: gmem
[platform/upstream/glib.git] / glib / gmem.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 /* 
28  * MT safe
29  */
30
31 #include "config.h"
32
33 #include "gmem.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <signal.h>
38
39 #include "gbacktrace.h"
40 #include "gtestutils.h"
41 #include "gthread.h"
42
43 #include "galias.h"
44
45 #define MEM_PROFILE_TABLE_SIZE 4096
46
47
48 /* notes on macros:
49  * having G_DISABLE_CHECKS defined disables use of glib_mem_profiler_table and
50  * g_mem_profile().
51  * REALLOC_0_WORKS is defined if g_realloc (NULL, x) works.
52  * SANE_MALLOC_PROTOS is defined if the systems malloc() and friends functions
53  * match the corresponding GLib prototypes, keep configure.in and gmem.h in sync here.
54  * g_mem_gc_friendly is TRUE, freed memory should be 0-wiped.
55  */
56
57 /* --- prototypes --- */
58 static gboolean g_mem_initialized = FALSE;
59 static void     g_mem_init_nomessage (void);
60
61
62 /* --- malloc wrappers --- */
63 #ifndef REALLOC_0_WORKS
64 static gpointer
65 standard_realloc (gpointer mem,
66                   gsize    n_bytes)
67 {
68   if (!mem)
69     return malloc (n_bytes);
70   else
71     return realloc (mem, n_bytes);
72 }
73 #endif  /* !REALLOC_0_WORKS */
74
75 #ifdef SANE_MALLOC_PROTOS
76 #  define standard_malloc       malloc
77 #  ifdef REALLOC_0_WORKS
78 #    define standard_realloc    realloc
79 #  endif /* REALLOC_0_WORKS */
80 #  define standard_free         free
81 #  define standard_calloc       calloc
82 #  define standard_try_malloc   malloc
83 #  define standard_try_realloc  realloc
84 #else   /* !SANE_MALLOC_PROTOS */
85 static gpointer
86 standard_malloc (gsize n_bytes)
87 {
88   return malloc (n_bytes);
89 }
90 #  ifdef REALLOC_0_WORKS
91 static gpointer
92 standard_realloc (gpointer mem,
93                   gsize    n_bytes)
94 {
95   return realloc (mem, n_bytes);
96 }
97 #  endif /* REALLOC_0_WORKS */
98 static void
99 standard_free (gpointer mem)
100 {
101   free (mem);
102 }
103 static gpointer
104 standard_calloc (gsize n_blocks,
105                  gsize n_bytes)
106 {
107   return calloc (n_blocks, n_bytes);
108 }
109 #define standard_try_malloc     standard_malloc
110 #define standard_try_realloc    standard_realloc
111 #endif  /* !SANE_MALLOC_PROTOS */
112
113
114 /* --- variables --- */
115 static GMemVTable glib_mem_vtable = {
116   standard_malloc,
117   standard_realloc,
118   standard_free,
119   standard_calloc,
120   standard_try_malloc,
121   standard_try_realloc,
122 };
123
124
125 /* --- functions --- */
126 gpointer
127 g_malloc (gsize n_bytes)
128 {
129   if (G_UNLIKELY (!g_mem_initialized))
130     g_mem_init_nomessage();
131   if (G_LIKELY (n_bytes))
132     {
133       gpointer mem;
134
135       mem = glib_mem_vtable.malloc (n_bytes);
136       if (mem)
137         return mem;
138
139       g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
140                G_STRLOC, n_bytes);
141     }
142
143   return NULL;
144 }
145
146 gpointer
147 g_malloc0 (gsize n_bytes)
148 {
149   if (G_UNLIKELY (!g_mem_initialized))
150     g_mem_init_nomessage();
151   if (G_LIKELY (n_bytes))
152     {
153       gpointer mem;
154
155       mem = glib_mem_vtable.calloc (1, n_bytes);
156       if (mem)
157         return mem;
158
159       g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
160                G_STRLOC, n_bytes);
161     }
162
163   return NULL;
164 }
165
166 gpointer
167 g_realloc (gpointer mem,
168            gsize    n_bytes)
169 {
170   if (G_UNLIKELY (!g_mem_initialized))
171     g_mem_init_nomessage();
172   if (G_LIKELY (n_bytes))
173     {
174       mem = glib_mem_vtable.realloc (mem, n_bytes);
175       if (mem)
176         return mem;
177
178       g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
179                G_STRLOC, n_bytes);
180     }
181
182   if (mem)
183     glib_mem_vtable.free (mem);
184
185   return NULL;
186 }
187
188 void
189 g_free (gpointer mem)
190 {
191   if (G_UNLIKELY (!g_mem_initialized))
192     g_mem_init_nomessage();
193   if (G_LIKELY (mem))
194     glib_mem_vtable.free (mem);
195 }
196
197 gpointer
198 g_try_malloc (gsize n_bytes)
199 {
200   if (G_UNLIKELY (!g_mem_initialized))
201     g_mem_init_nomessage();
202   if (G_LIKELY (n_bytes))
203     return glib_mem_vtable.try_malloc (n_bytes);
204   else
205     return NULL;
206 }
207
208 gpointer
209 g_try_malloc0 (gsize n_bytes)
210 {
211   gpointer mem;
212
213   mem = g_try_malloc (n_bytes);
214
215   if (mem)
216     memset (mem, 0, n_bytes);
217
218   return mem;
219 }
220
221 gpointer
222 g_try_realloc (gpointer mem,
223                gsize    n_bytes)
224 {
225   if (G_UNLIKELY (!g_mem_initialized))
226     g_mem_init_nomessage();
227   if (G_LIKELY (n_bytes))
228     return glib_mem_vtable.try_realloc (mem, n_bytes);
229
230   if (mem)
231     glib_mem_vtable.free (mem);
232
233   return NULL;
234 }
235
236
237 #define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((a) > G_MAXSIZE / (b)))
238
239 gpointer
240 g_malloc_n (gsize n_blocks,
241             gsize n_block_bytes)
242 {
243   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
244     {
245       if (G_UNLIKELY (!g_mem_initialized))
246         g_mem_init_nomessage();
247
248       g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
249                G_STRLOC, n_blocks, n_block_bytes);
250     }
251
252   return g_malloc (n_blocks * n_block_bytes);
253 }
254
255 gpointer
256 g_malloc0_n (gsize n_blocks,
257              gsize n_block_bytes)
258 {
259   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
260     {
261       if (G_UNLIKELY (!g_mem_initialized))
262         g_mem_init_nomessage();
263
264       g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
265                G_STRLOC, n_blocks, n_block_bytes);
266     }
267
268   return g_malloc0 (n_blocks * n_block_bytes);
269 }
270
271 gpointer
272 g_realloc_n (gpointer mem,
273              gsize    n_blocks,
274              gsize    n_block_bytes)
275 {
276   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
277     {
278       if (G_UNLIKELY (!g_mem_initialized))
279         g_mem_init_nomessage();
280
281       g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
282                G_STRLOC, n_blocks, n_block_bytes);
283     }
284
285   return g_realloc (mem, n_blocks * n_block_bytes);
286 }
287
288 gpointer
289 g_try_malloc_n (gsize n_blocks,
290                 gsize n_block_bytes)
291 {
292   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
293     return NULL;
294
295   return g_try_malloc (n_blocks * n_block_bytes);
296 }
297
298 gpointer
299 g_try_malloc0_n (gsize n_blocks,
300                  gsize n_block_bytes)
301 {
302   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
303     return NULL;
304
305   return g_try_malloc0 (n_blocks * n_block_bytes);
306 }
307
308 gpointer
309 g_try_realloc_n (gpointer mem,
310                  gsize    n_blocks,
311                  gsize    n_block_bytes)
312 {
313   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
314     return NULL;
315
316   return g_try_realloc (mem, n_blocks * n_block_bytes);
317 }
318
319
320
321 static gpointer
322 fallback_calloc (gsize n_blocks,
323                  gsize n_block_bytes)
324 {
325   gsize l = n_blocks * n_block_bytes;
326   gpointer mem = glib_mem_vtable.malloc (l);
327
328   if (mem)
329     memset (mem, 0, l);
330
331   return mem;
332 }
333
334 static gboolean vtable_set = FALSE;
335
336 /**
337  * g_mem_is_system_malloc
338  * 
339  * Checks whether the allocator used by g_malloc() is the system's
340  * malloc implementation. If it returns %TRUE memory allocated with
341  * malloc() can be used interchangeable with memory allocated using g_malloc(). 
342  * This function is useful for avoiding an extra copy of allocated memory returned
343  * by a non-GLib-based API.
344  *
345  * A different allocator can be set using g_mem_set_vtable().
346  *
347  * Return value: if %TRUE, malloc() and g_malloc() can be mixed.
348  **/
349 gboolean
350 g_mem_is_system_malloc (void)
351 {
352   return !vtable_set;
353 }
354
355 void
356 g_mem_set_vtable (GMemVTable *vtable)
357 {
358   if (!vtable_set)
359     {
360       if (vtable->malloc && vtable->realloc && vtable->free)
361         {
362           glib_mem_vtable.malloc = vtable->malloc;
363           glib_mem_vtable.realloc = vtable->realloc;
364           glib_mem_vtable.free = vtable->free;
365           glib_mem_vtable.calloc = vtable->calloc ? vtable->calloc : fallback_calloc;
366           glib_mem_vtable.try_malloc = vtable->try_malloc ? vtable->try_malloc : glib_mem_vtable.malloc;
367           glib_mem_vtable.try_realloc = vtable->try_realloc ? vtable->try_realloc : glib_mem_vtable.realloc;
368           vtable_set = TRUE;
369         }
370       else
371         g_warning (G_STRLOC ": memory allocation vtable lacks one of malloc(), realloc() or free()");
372     }
373   else
374     g_warning (G_STRLOC ": memory allocation vtable can only be set once at startup");
375 }
376
377
378 /* --- memory profiling and checking --- */
379 #ifdef  G_DISABLE_CHECKS
380 GMemVTable *glib_mem_profiler_table = &glib_mem_vtable;
381 void
382 g_mem_profile (void)
383 {
384 }
385 #else   /* !G_DISABLE_CHECKS */
386 typedef enum {
387   PROFILER_FREE         = 0,
388   PROFILER_ALLOC        = 1,
389   PROFILER_RELOC        = 2,
390   PROFILER_ZINIT        = 4
391 } ProfilerJob;
392 static guint *profile_data = NULL;
393 static gsize profile_allocs = 0;
394 static gsize profile_zinit = 0;
395 static gsize profile_frees = 0;
396 static GMutex *gmem_profile_mutex = NULL;
397 #ifdef  G_ENABLE_DEBUG
398 static volatile gsize g_trap_free_size = 0;
399 static volatile gsize g_trap_realloc_size = 0;
400 static volatile gsize g_trap_malloc_size = 0;
401 #endif  /* G_ENABLE_DEBUG */
402
403 #define PROFILE_TABLE(f1,f2,f3)   ( ( ((f3) << 2) | ((f2) << 1) | (f1) ) * (MEM_PROFILE_TABLE_SIZE + 1))
404
405 static void
406 profiler_log (ProfilerJob job,
407               gsize       n_bytes,
408               gboolean    success)
409 {
410   g_mutex_lock (gmem_profile_mutex);
411   if (!profile_data)
412     {
413       profile_data = standard_calloc ((MEM_PROFILE_TABLE_SIZE + 1) * 8, 
414                                       sizeof (profile_data[0]));
415       if (!profile_data)        /* memory system kiddin' me, eh? */
416         {
417           g_mutex_unlock (gmem_profile_mutex);
418           return;
419         }
420     }
421
422   if (n_bytes < MEM_PROFILE_TABLE_SIZE)
423     profile_data[n_bytes + PROFILE_TABLE ((job & PROFILER_ALLOC) != 0,
424                                           (job & PROFILER_RELOC) != 0,
425                                           success != 0)] += 1;
426   else
427     profile_data[MEM_PROFILE_TABLE_SIZE + PROFILE_TABLE ((job & PROFILER_ALLOC) != 0,
428                                                          (job & PROFILER_RELOC) != 0,
429                                                          success != 0)] += 1;
430   if (success)
431     {
432       if (job & PROFILER_ALLOC)
433         {
434           profile_allocs += n_bytes;
435           if (job & PROFILER_ZINIT)
436             profile_zinit += n_bytes;
437         }
438       else
439         profile_frees += n_bytes;
440     }
441   g_mutex_unlock (gmem_profile_mutex);
442 }
443
444 static void
445 profile_print_locked (guint   *local_data,
446                       gboolean success)
447 {
448   gboolean need_header = TRUE;
449   guint i;
450
451   for (i = 0; i <= MEM_PROFILE_TABLE_SIZE; i++)
452     {
453       glong t_malloc = local_data[i + PROFILE_TABLE (1, 0, success)];
454       glong t_realloc = local_data[i + PROFILE_TABLE (1, 1, success)];
455       glong t_free = local_data[i + PROFILE_TABLE (0, 0, success)];
456       glong t_refree = local_data[i + PROFILE_TABLE (0, 1, success)];
457       
458       if (!t_malloc && !t_realloc && !t_free && !t_refree)
459         continue;
460       else if (need_header)
461         {
462           need_header = FALSE;
463           g_print (" blocks of | allocated  | freed      | allocated  | freed      | n_bytes   \n");
464           g_print ("  n_bytes  | n_times by | n_times by | n_times by | n_times by | remaining \n");
465           g_print ("           | malloc()   | free()     | realloc()  | realloc()  |           \n");
466           g_print ("===========|============|============|============|============|===========\n");
467         }
468       if (i < MEM_PROFILE_TABLE_SIZE)
469         g_print ("%10u | %10ld | %10ld | %10ld | %10ld |%+11ld\n",
470                  i, t_malloc, t_free, t_realloc, t_refree,
471                  (t_malloc - t_free + t_realloc - t_refree) * i);
472       else if (i >= MEM_PROFILE_TABLE_SIZE)
473         g_print ("   >%6u | %10ld | %10ld | %10ld | %10ld |        ***\n",
474                  i, t_malloc, t_free, t_realloc, t_refree);
475     }
476   if (need_header)
477     g_print (" --- none ---\n");
478 }
479
480 void
481 g_mem_profile (void)
482 {
483   guint local_data[(MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0])];
484   gsize local_allocs;
485   gsize local_zinit;
486   gsize local_frees;
487
488   if (G_UNLIKELY (!g_mem_initialized))
489     g_mem_init_nomessage();
490
491   g_mutex_lock (gmem_profile_mutex);
492
493   local_allocs = profile_allocs;
494   local_zinit = profile_zinit;
495   local_frees = profile_frees;
496
497   if (!profile_data)
498     {
499       g_mutex_unlock (gmem_profile_mutex);
500       return;
501     }
502
503   memcpy (local_data, profile_data, 
504           (MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0]));
505   
506   g_mutex_unlock (gmem_profile_mutex);
507
508   g_print ("GLib Memory statistics (successful operations):\n");
509   profile_print_locked (local_data, TRUE);
510   g_print ("GLib Memory statistics (failing operations):\n");
511   profile_print_locked (local_data, FALSE);
512   g_print ("Total bytes: allocated=%"G_GSIZE_FORMAT", "
513            "zero-initialized=%"G_GSIZE_FORMAT" (%.2f%%), "
514            "freed=%"G_GSIZE_FORMAT" (%.2f%%), "
515            "remaining=%"G_GSIZE_FORMAT"\n",
516            local_allocs,
517            local_zinit,
518            ((gdouble) local_zinit) / local_allocs * 100.0,
519            local_frees,
520            ((gdouble) local_frees) / local_allocs * 100.0,
521            local_allocs - local_frees);
522 }
523
524 static gpointer
525 profiler_try_malloc (gsize n_bytes)
526 {
527   gsize *p;
528
529 #ifdef  G_ENABLE_DEBUG
530   if (g_trap_malloc_size == n_bytes)
531     G_BREAKPOINT ();
532 #endif  /* G_ENABLE_DEBUG */
533
534   p = standard_malloc (sizeof (gsize) * 2 + n_bytes);
535
536   if (p)
537     {
538       p[0] = 0;         /* free count */
539       p[1] = n_bytes;   /* length */
540       profiler_log (PROFILER_ALLOC, n_bytes, TRUE);
541       p += 2;
542     }
543   else
544     profiler_log (PROFILER_ALLOC, n_bytes, FALSE);
545   
546   return p;
547 }
548
549 static gpointer
550 profiler_malloc (gsize n_bytes)
551 {
552   gpointer mem = profiler_try_malloc (n_bytes);
553
554   if (!mem)
555     g_mem_profile ();
556
557   return mem;
558 }
559
560 static gpointer
561 profiler_calloc (gsize n_blocks,
562                  gsize n_block_bytes)
563 {
564   gsize l = n_blocks * n_block_bytes;
565   gsize *p;
566
567 #ifdef  G_ENABLE_DEBUG
568   if (g_trap_malloc_size == l)
569     G_BREAKPOINT ();
570 #endif  /* G_ENABLE_DEBUG */
571   
572   p = standard_calloc (1, sizeof (gsize) * 2 + l);
573
574   if (p)
575     {
576       p[0] = 0;         /* free count */
577       p[1] = l;         /* length */
578       profiler_log (PROFILER_ALLOC | PROFILER_ZINIT, l, TRUE);
579       p += 2;
580     }
581   else
582     {
583       profiler_log (PROFILER_ALLOC | PROFILER_ZINIT, l, FALSE);
584       g_mem_profile ();
585     }
586
587   return p;
588 }
589
590 static void
591 profiler_free (gpointer mem)
592 {
593   gsize *p = mem;
594
595   p -= 2;
596   if (p[0])     /* free count */
597     {
598       g_warning ("free(%p): memory has been freed %"G_GSIZE_FORMAT" times already",
599                  p + 2, p[0]);
600       profiler_log (PROFILER_FREE,
601                     p[1],       /* length */
602                     FALSE);
603     }
604   else
605     {
606 #ifdef  G_ENABLE_DEBUG
607       if (g_trap_free_size == p[1])
608         G_BREAKPOINT ();
609 #endif  /* G_ENABLE_DEBUG */
610
611       profiler_log (PROFILER_FREE,
612                     p[1],       /* length */
613                     TRUE);
614       memset (p + 2, 0xaa, p[1]);
615
616       /* for all those that miss standard_free (p); in this place, yes,
617        * we do leak all memory when profiling, and that is intentional
618        * to catch double frees. patch submissions are futile.
619        */
620     }
621   p[0] += 1;
622 }
623
624 static gpointer
625 profiler_try_realloc (gpointer mem,
626                       gsize    n_bytes)
627 {
628   gsize *p = mem;
629
630   p -= 2;
631
632 #ifdef  G_ENABLE_DEBUG
633   if (g_trap_realloc_size == n_bytes)
634     G_BREAKPOINT ();
635 #endif  /* G_ENABLE_DEBUG */
636   
637   if (mem && p[0])      /* free count */
638     {
639       g_warning ("realloc(%p, %"G_GSIZE_FORMAT"): "
640                  "memory has been freed %"G_GSIZE_FORMAT" times already",
641                  p + 2, (gsize) n_bytes, p[0]);
642       profiler_log (PROFILER_ALLOC | PROFILER_RELOC, n_bytes, FALSE);
643
644       return NULL;
645     }
646   else
647     {
648       p = standard_realloc (mem ? p : NULL, sizeof (gsize) * 2 + n_bytes);
649
650       if (p)
651         {
652           if (mem)
653             profiler_log (PROFILER_FREE | PROFILER_RELOC, p[1], TRUE);
654           p[0] = 0;
655           p[1] = n_bytes;
656           profiler_log (PROFILER_ALLOC | PROFILER_RELOC, p[1], TRUE);
657           p += 2;
658         }
659       else
660         profiler_log (PROFILER_ALLOC | PROFILER_RELOC, n_bytes, FALSE);
661
662       return p;
663     }
664 }
665
666 static gpointer
667 profiler_realloc (gpointer mem,
668                   gsize    n_bytes)
669 {
670   mem = profiler_try_realloc (mem, n_bytes);
671
672   if (!mem)
673     g_mem_profile ();
674
675   return mem;
676 }
677
678 static GMemVTable profiler_table = {
679   profiler_malloc,
680   profiler_realloc,
681   profiler_free,
682   profiler_calloc,
683   profiler_try_malloc,
684   profiler_try_realloc,
685 };
686 GMemVTable *glib_mem_profiler_table = &profiler_table;
687
688 #endif  /* !G_DISABLE_CHECKS */
689
690 /* --- MemChunks --- */
691 /**
692  * SECTION: allocators
693  * @title: Memory Allocators
694  * @short_description: deprecated way to allocate chunks of memory for
695  *                     GList, GSList and GNode
696  *
697  * Prior to 2.10, #GAllocator was used as an efficient way to allocate
698  * small pieces of memory for use with the #GList, #GSList and #GNode
699  * data structures. Since 2.10, it has been completely replaced by the
700  * <link linkend="glib-Memory-Slices">slice allocator</link> and
701  * deprecated.
702  **/
703
704 /**
705  * SECTION: memory_chunks
706  * @title: Memory Chunks
707  * @short_description: deprecated way to allocate groups of equal-sized
708  *                     chunks of memory
709  *
710  * Memory chunks provide an space-efficient way to allocate equal-sized
711  * pieces of memory, called atoms. However, due to the administrative
712  * overhead (in particular for #G_ALLOC_AND_FREE, and when used from
713  * multiple threads), they are in practise often slower than direct use
714  * of g_malloc(). Therefore, memory chunks have been deprecated in
715  * favor of the <link linkend="glib-Memory-Slices">slice
716  * allocator</link>, which has been added in 2.10. All internal uses of
717  * memory chunks in GLib have been converted to the
718  * <literal>g_slice</literal> API.
719  *
720  * There are two types of memory chunks, #G_ALLOC_ONLY, and
721  * #G_ALLOC_AND_FREE. <itemizedlist> <listitem><para> #G_ALLOC_ONLY
722  * chunks only allow allocation of atoms. The atoms can never be freed
723  * individually. The memory chunk can only be free in its entirety.
724  * </para></listitem> <listitem><para> #G_ALLOC_AND_FREE chunks do
725  * allow atoms to be freed individually. The disadvantage of this is
726  * that the memory chunk has to keep track of which atoms have been
727  * freed. This results in more memory being used and a slight
728  * degradation in performance. </para></listitem> </itemizedlist>
729  *
730  * To create a memory chunk use g_mem_chunk_new() or the convenience
731  * macro g_mem_chunk_create().
732  *
733  * To allocate a new atom use g_mem_chunk_alloc(),
734  * g_mem_chunk_alloc0(), or the convenience macros g_chunk_new() or
735  * g_chunk_new0().
736  *
737  * To free an atom use g_mem_chunk_free(), or the convenience macro
738  * g_chunk_free(). (Atoms can only be freed if the memory chunk is
739  * created with the type set to #G_ALLOC_AND_FREE.)
740  *
741  * To free any blocks of memory which are no longer being used, use
742  * g_mem_chunk_clean(). To clean all memory chunks, use g_blow_chunks().
743  *
744  * To reset the memory chunk, freeing all of the atoms, use
745  * g_mem_chunk_reset().
746  *
747  * To destroy a memory chunk, use g_mem_chunk_destroy().
748  *
749  * To help debug memory chunks, use g_mem_chunk_info() and
750  * g_mem_chunk_print().
751  *
752  * <example>
753  *  <title>Using a #GMemChunk</title>
754  *  <programlisting>
755  *   GMemChunk *mem_chunk;
756  *   gchar *mem[10000];
757  *   gint i;
758  *
759  *   /<!-- -->* Create a GMemChunk with atoms 50 bytes long, and memory
760  *      blocks holding 100 bytes. Note that this means that only 2 atoms
761  *      fit into each memory block and so isn't very efficient. *<!-- -->/
762  *   mem_chunk = g_mem_chunk_new ("test mem chunk", 50, 100, G_ALLOC_AND_FREE);
763  *   /<!-- -->* Now allocate 10000 atoms. *<!-- -->/
764  *   for (i = 0; i &lt; 10000; i++)
765  *     {
766  *       mem[i] = g_chunk_new (gchar, mem_chunk);
767  *       /<!-- -->* Fill in the atom memory with some junk. *<!-- -->/
768  *       for (j = 0; j &lt; 50; j++)
769  *         mem[i][j] = i * j;
770  *     }
771  *   /<!-- -->* Now free all of the atoms. Note that since we are going to
772  *      destroy the GMemChunk, this wouldn't normally be used. *<!-- -->/
773  *   for (i = 0; i &lt; 10000; i++)
774  *     {
775  *       g_mem_chunk_free (mem_chunk, mem[i]);
776  *     }
777  *   /<!-- -->* We are finished with the GMemChunk, so we destroy it. *<!-- -->/
778  *   g_mem_chunk_destroy (mem_chunk);
779  *  </programlisting>
780  * </example>
781  *
782  * <example>
783  *  <title>Using a #GMemChunk with data structures</title>
784  *  <programlisting>
785  *    GMemChunk *array_mem_chunk;
786  *    GRealArray *array;
787  *    /<!-- -->* Create a GMemChunk to hold GRealArray structures, using
788  *       the g_mem_chunk_create(<!-- -->) convenience macro. We want 1024 atoms in each
789  *       memory block, and we want to be able to free individual atoms. *<!-- -->/
790  *    array_mem_chunk = g_mem_chunk_create (GRealArray, 1024, G_ALLOC_AND_FREE);
791  *    /<!-- -->* Allocate one atom, using the g_chunk_new(<!-- -->) convenience macro. *<!-- -->/
792  *    array = g_chunk_new (GRealArray, array_mem_chunk);
793  *    /<!-- -->* We can now use array just like a normal pointer to a structure. *<!-- -->/
794  *    array->data            = NULL;
795  *    array->len             = 0;
796  *    array->alloc           = 0;
797  *    array->zero_terminated = (zero_terminated ? 1 : 0);
798  *    array->clear           = (clear ? 1 : 0);
799  *    array->elt_size        = elt_size;
800  *    /<!-- -->* We can free the element, so it can be reused. *<!-- -->/
801  *    g_chunk_free (array, array_mem_chunk);
802  *    /<!-- -->* We destroy the GMemChunk when we are finished with it. *<!-- -->/
803  *    g_mem_chunk_destroy (array_mem_chunk);
804  *  </programlisting>
805  * </example>
806  **/
807
808 #ifndef G_ALLOC_AND_FREE
809
810 /**
811  * GAllocator:
812  *
813  * The #GAllocator struct contains private data. and should only be
814  * accessed using the following functions.
815  **/
816 typedef struct _GAllocator GAllocator;
817
818 /**
819  * GMemChunk:
820  *
821  * The #GMemChunk struct is an opaque data structure representing a
822  * memory chunk. It should be accessed only through the use of the
823  * following functions.
824  **/
825 typedef struct _GMemChunk  GMemChunk;
826
827 /**
828  * G_ALLOC_ONLY:
829  *
830  * Specifies the type of a #GMemChunk. Used in g_mem_chunk_new() and
831  * g_mem_chunk_create() to specify that atoms will never be freed
832  * individually.
833  **/
834 #define G_ALLOC_ONLY      1
835
836 /**
837  * G_ALLOC_AND_FREE:
838  *
839  * Specifies the type of a #GMemChunk. Used in g_mem_chunk_new() and
840  * g_mem_chunk_create() to specify that atoms will be freed
841  * individually.
842  **/
843 #define G_ALLOC_AND_FREE  2
844 #endif
845
846 struct _GMemChunk {
847   guint alloc_size;           /* the size of an atom */
848 };
849
850 /**
851  * g_mem_chunk_new:
852  * @name: a string to identify the #GMemChunk. It is not copied so it
853  *        should be valid for the lifetime of the #GMemChunk. It is
854  *        only used in g_mem_chunk_print(), which is used for debugging.
855  * @atom_size: the size, in bytes, of each element in the #GMemChunk.
856  * @area_size: the size, in bytes, of each block of memory allocated to
857  *             contain the atoms.
858  * @type: the type of the #GMemChunk.  #G_ALLOC_AND_FREE is used if the
859  *        atoms will be freed individually.  #G_ALLOC_ONLY should be
860  *        used if atoms will never be freed individually.
861  *        #G_ALLOC_ONLY is quicker, since it does not need to track
862  *        free atoms, but it obviously wastes memory if you no longer
863  *        need many of the atoms.
864  * @Returns: the new #GMemChunk.
865  *
866  * Creates a new #GMemChunk.
867  *
868  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
869  *                  allocator</link> instead
870  **/
871 GMemChunk*
872 g_mem_chunk_new (const gchar  *name,
873                  gint          atom_size,
874                  gsize         area_size,
875                  gint          type)
876 {
877   GMemChunk *mem_chunk;
878   g_return_val_if_fail (atom_size > 0, NULL);
879
880   mem_chunk = g_slice_new (GMemChunk);
881   mem_chunk->alloc_size = atom_size;
882   return mem_chunk;
883 }
884
885 /**
886  * g_mem_chunk_destroy:
887  * @mem_chunk: a #GMemChunk.
888  *
889  * Frees all of the memory allocated for a #GMemChunk.
890  *
891  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
892  *                  allocator</link> instead
893  **/
894 void
895 g_mem_chunk_destroy (GMemChunk *mem_chunk)
896 {
897   g_return_if_fail (mem_chunk != NULL);
898   
899   g_slice_free (GMemChunk, mem_chunk);
900 }
901
902 /**
903  * g_mem_chunk_alloc:
904  * @mem_chunk: a #GMemChunk.
905  * @Returns: a pointer to the allocated atom.
906  *
907  * Allocates an atom of memory from a #GMemChunk.
908  *
909  * Deprecated:2.10: Use g_slice_alloc() instead
910  **/
911 gpointer
912 g_mem_chunk_alloc (GMemChunk *mem_chunk)
913 {
914   g_return_val_if_fail (mem_chunk != NULL, NULL);
915   
916   return g_slice_alloc (mem_chunk->alloc_size);
917 }
918
919 /**
920  * g_mem_chunk_alloc0:
921  * @mem_chunk: a #GMemChunk.
922  * @Returns: a pointer to the allocated atom.
923  *
924  * Allocates an atom of memory from a #GMemChunk, setting the memory to
925  * 0.
926  *
927  * Deprecated:2.10: Use g_slice_alloc0() instead
928  **/
929 gpointer
930 g_mem_chunk_alloc0 (GMemChunk *mem_chunk)
931 {
932   g_return_val_if_fail (mem_chunk != NULL, NULL);
933   
934   return g_slice_alloc0 (mem_chunk->alloc_size);
935 }
936
937 /**
938  * g_mem_chunk_free:
939  * @mem_chunk: a #GMemChunk.
940  * @mem: a pointer to the atom to free.
941  *
942  * Frees an atom in a #GMemChunk. This should only be called if the
943  * #GMemChunk was created with #G_ALLOC_AND_FREE. Otherwise it will
944  * simply return.
945  *
946  * Deprecated:2.10: Use g_slice_free1() instead
947  **/
948 void
949 g_mem_chunk_free (GMemChunk *mem_chunk,
950                   gpointer   mem)
951 {
952   g_return_if_fail (mem_chunk != NULL);
953   
954   g_slice_free1 (mem_chunk->alloc_size, mem);
955 }
956
957 /**
958  * g_mem_chunk_clean:
959  * @mem_chunk: a #GMemChunk.
960  *
961  * Frees any blocks in a #GMemChunk which are no longer being used.
962  *
963  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
964  *                  allocator</link> instead
965  **/
966 void    g_mem_chunk_clean       (GMemChunk *mem_chunk)  {}
967
968 /**
969  * g_mem_chunk_reset:
970  * @mem_chunk: a #GMemChunk.
971  *
972  * Resets a GMemChunk to its initial state. It frees all of the
973  * currently allocated blocks of memory.
974  *
975  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
976  *                  allocator</link> instead
977  **/
978 void    g_mem_chunk_reset       (GMemChunk *mem_chunk)  {}
979
980
981 /**
982  * g_mem_chunk_print:
983  * @mem_chunk: a #GMemChunk.
984  *
985  * Outputs debugging information for a #GMemChunk. It outputs the name
986  * of the #GMemChunk (set with g_mem_chunk_new()), the number of bytes
987  * used, and the number of blocks of memory allocated.
988  *
989  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
990  *                  allocator</link> instead
991  **/
992 void    g_mem_chunk_print       (GMemChunk *mem_chunk)  {}
993
994
995 /**
996  * g_mem_chunk_info:
997  *
998  * Outputs debugging information for all #GMemChunk objects currently
999  * in use. It outputs the number of #GMemChunk objects currently
1000  * allocated, and calls g_mem_chunk_print() to output information on
1001  * each one.
1002  *
1003  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
1004  *                  allocator</link> instead
1005  **/
1006 void    g_mem_chunk_info        (void)                  {}
1007
1008 /**
1009  * g_blow_chunks:
1010  *
1011  * Calls g_mem_chunk_clean() on all #GMemChunk objects.
1012  *
1013  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
1014  *                  allocator</link> instead
1015  **/
1016 void    g_blow_chunks           (void)                  {}
1017
1018 /**
1019  * g_chunk_new0:
1020  * @type: the type of the #GMemChunk atoms, typically a structure name.
1021  * @chunk: a #GMemChunk.
1022  * @Returns: a pointer to the allocated atom, cast to a pointer to
1023  *           @type.
1024  *
1025  * A convenience macro to allocate an atom of memory from a #GMemChunk.
1026  * It calls g_mem_chunk_alloc0() and casts the returned atom to a
1027  * pointer to the given type, avoiding a type cast in the source code.
1028  *
1029  * Deprecated:2.10: Use g_slice_new0() instead
1030  **/
1031
1032 /**
1033  * g_chunk_free:
1034  * @mem: a pointer to the atom to be freed.
1035  * @mem_chunk: a #GMemChunk.
1036  *
1037  * A convenience macro to free an atom of memory from a #GMemChunk. It
1038  * simply switches the arguments and calls g_mem_chunk_free() It is
1039  * included simply to complement the other convenience macros,
1040  * g_chunk_new() and g_chunk_new0().
1041  *
1042  * Deprecated:2.10: Use g_slice_free() instead
1043  **/
1044
1045 /**
1046  * g_chunk_new:
1047  * @type: the type of the #GMemChunk atoms, typically a structure name.
1048  * @chunk: a #GMemChunk.
1049  * @Returns: a pointer to the allocated atom, cast to a pointer to
1050  *           @type.
1051  *
1052  * A convenience macro to allocate an atom of memory from a #GMemChunk.
1053  * It calls g_mem_chunk_alloc() and casts the returned atom to a
1054  * pointer to the given type, avoiding a type cast in the source code.
1055  *
1056  * Deprecated:2.10: Use g_slice_new() instead
1057  **/
1058
1059 /**
1060  * g_mem_chunk_create:
1061  * @type: the type of the atoms, typically a structure name.
1062  * @pre_alloc: the number of atoms to store in each block of memory.
1063  * @alloc_type: the type of the #GMemChunk.  #G_ALLOC_AND_FREE is used
1064  *              if the atoms will be freed individually.  #G_ALLOC_ONLY
1065  *              should be used if atoms will never be freed
1066  *              individually.  #G_ALLOC_ONLY is quicker, since it does
1067  *              not need to track free atoms, but it obviously wastes
1068  *              memory if you no longer need many of the atoms.
1069  * @Returns: the new #GMemChunk.
1070  *
1071  * A convenience macro for creating a new #GMemChunk. It calls
1072  * g_mem_chunk_new(), using the given type to create the #GMemChunk
1073  * name. The atom size is determined using
1074  * <function>sizeof()</function>, and the area size is calculated by
1075  * multiplying the @pre_alloc parameter with the atom size.
1076  *
1077  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
1078  *                  allocator</link> instead
1079  **/
1080
1081
1082 /**
1083  * g_allocator_new:
1084  * @name: the name of the #GAllocator. This name is used to set the
1085  *        name of the #GMemChunk used by the #GAllocator, and is only
1086  *        used for debugging.
1087  * @n_preallocs: the number of elements in each block of memory
1088  *               allocated.  Larger blocks mean less calls to
1089  *               g_malloc(), but some memory may be wasted.  (GLib uses
1090  *               128 elements per block by default.) The value must be
1091  *               between 1 and 65535.
1092  * @Returns: a new #GAllocator.
1093  *
1094  * Creates a new #GAllocator.
1095  *
1096  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
1097  *                  allocator</link> instead
1098  **/
1099 GAllocator*
1100 g_allocator_new (const gchar *name,
1101                  guint        n_preallocs)
1102 {
1103   static struct _GAllocator {
1104     gchar      *name;
1105     guint16     n_preallocs;
1106     guint       is_unused : 1;
1107     guint       type : 4;
1108     GAllocator *last;
1109     GMemChunk  *mem_chunk;
1110     gpointer    free_list;
1111   } dummy = {
1112     "GAllocator is deprecated", 1, TRUE, 0, NULL, NULL, NULL,
1113   };
1114   /* some (broken) GAllocator uses depend on non-NULL allocators */
1115   return (void*) &dummy;
1116 }
1117
1118 /**
1119  * g_allocator_free:
1120  * @allocator: a #GAllocator.
1121  *
1122  * Frees all of the memory allocated by the #GAllocator.
1123  *
1124  * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
1125  *                  allocator</link> instead
1126  **/
1127 void
1128 g_allocator_free (GAllocator *allocator)
1129 {
1130 }
1131
1132 #ifdef ENABLE_GC_FRIENDLY_DEFAULT
1133 gboolean g_mem_gc_friendly = TRUE;
1134 #else
1135 gboolean g_mem_gc_friendly = FALSE;
1136 #endif
1137
1138 static void
1139 g_mem_init_nomessage (void)
1140 {
1141   gchar buffer[1024];
1142   const gchar *val;
1143   const GDebugKey keys[] = {
1144     { "gc-friendly", 1 },
1145   };
1146   gint flags;
1147   if (g_mem_initialized)
1148     return;
1149   /* don't use g_malloc/g_message here */
1150   val = _g_getenv_nomalloc ("G_DEBUG", buffer);
1151   flags = !val ? 0 : g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));
1152   if (flags & 1)        /* gc-friendly */
1153     {
1154       g_mem_gc_friendly = TRUE;
1155     }
1156   g_mem_initialized = TRUE;
1157 }
1158
1159 void
1160 _g_mem_thread_init_noprivate_nomessage (void)
1161 {
1162   /* we may only create mutexes here, locking/
1163    * unlocking a mutex does not yet work.
1164    */
1165   g_mem_init_nomessage();
1166 #ifndef G_DISABLE_CHECKS
1167   gmem_profile_mutex = g_mutex_new ();
1168 #endif
1169 }
1170
1171 #define __G_MEM_C__
1172 #include "galiasdef.c"