X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgmem.c;h=6a108ee9e0e38627a3d963b9cc651f11b121f7c1;hb=ea4f9ce8a060d53cbc299e4c384089f6cc926caa;hp=84029f7a36a3bf2f937c30b3fe645ff12fc4ba05;hpb=63732bdf5ec0edc75a58c39fbbb9e98f8f65d001;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gmem.c b/glib/gmem.c index 84029f7..6a108ee 100644 --- a/glib/gmem.c +++ b/glib/gmem.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . */ /* @@ -30,183 +28,427 @@ #include "config.h" +#include "gmem.h" + #include #include #include -#include "glib.h" -#include "gthreadinit.h" -#include "galias.h" +#include "gslice.h" +#include "gbacktrace.h" +#include "gtestutils.h" +#include "gthread.h" +#include "glib_trace.h" + +#define MEM_PROFILE_TABLE_SIZE 4096 + /* notes on macros: * having G_DISABLE_CHECKS defined disables use of glib_mem_profiler_table and * g_mem_profile(). - * REALLOC_0_WORKS is defined if g_realloc (NULL, x) works. - * SANE_MALLOC_PROTOS is defined if the systems malloc() and friends functions - * match the corresponding GLib prototypes, keep configure.in and gmem.h in sync here. - * if ENABLE_GC_FRIENDLY is defined, freed memory should be 0-wiped. + * If g_mem_gc_friendly is TRUE, freed memory should be 0-wiped. */ -#define MEM_PROFILE_TABLE_SIZE 4096 - -#ifndef REALLOC_0_WORKS -static gpointer -standard_realloc (gpointer mem, - gsize n_bytes) -{ - if (!mem) - return malloc (n_bytes); - else - return realloc (mem, n_bytes); -} -#endif /* !REALLOC_0_WORKS */ - -#ifdef SANE_MALLOC_PROTOS -# define standard_malloc malloc -# ifdef REALLOC_0_WORKS -# define standard_realloc realloc -# endif /* REALLOC_0_WORKS */ -# define standard_free free -# define standard_calloc calloc -# define standard_try_malloc malloc -# define standard_try_realloc realloc -#else /* !SANE_MALLOC_PROTOS */ -static gpointer -standard_malloc (gsize n_bytes) -{ - return malloc (n_bytes); -} -# ifdef REALLOC_0_WORKS -static gpointer -standard_realloc (gpointer mem, - gsize n_bytes) -{ - return realloc (mem, n_bytes); -} -# endif /* REALLOC_0_WORKS */ -static void -standard_free (gpointer mem) -{ - free (mem); -} -static gpointer -standard_calloc (gsize n_blocks, - gsize n_bytes) -{ - return calloc (n_blocks, n_bytes); -} -#define standard_try_malloc standard_malloc -#define standard_try_realloc standard_realloc -#endif /* !SANE_MALLOC_PROTOS */ - - /* --- variables --- */ static GMemVTable glib_mem_vtable = { - standard_malloc, - standard_realloc, - standard_free, - standard_calloc, - standard_try_malloc, - standard_try_realloc, + malloc, + realloc, + free, + calloc, + malloc, + realloc, }; +/** + * SECTION:memory + * @Short_Description: general memory-handling + * @Title: Memory Allocation + * + * These functions provide support for allocating and freeing memory. + * + * If any call to allocate memory fails, the application is terminated. + * This also means that there is no need to check if the call succeeded. + * + * It's important to match g_malloc() (and wrappers such as g_new()) with + * g_free(), g_slice_alloc() (and wrappers such as g_slice_new()) with + * g_slice_free(), plain malloc() with free(), and (if you're using C++) + * new with delete and new[] with delete[]. Otherwise bad things can happen, + * since these allocators may use different memory pools (and new/delete call + * constructors and destructors). See also g_mem_set_vtable(). + */ /* --- functions --- */ +/** + * g_malloc: + * @n_bytes: the number of bytes to allocate + * + * Allocates @n_bytes bytes of memory. + * If @n_bytes is 0 it returns %NULL. + * + * Returns: a pointer to the allocated memory + */ gpointer -g_malloc (gulong n_bytes) +g_malloc (gsize n_bytes) { - if (n_bytes) + if (G_LIKELY (n_bytes)) { gpointer mem; mem = glib_mem_vtable.malloc (n_bytes); + TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0)); if (mem) return mem; - g_error ("%s: failed to allocate %lu bytes", G_STRLOC, n_bytes); + g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes", + G_STRLOC, n_bytes); } + TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0)); + return NULL; } +/** + * g_malloc0: + * @n_bytes: the number of bytes to allocate + * + * Allocates @n_bytes bytes of memory, initialized to 0's. + * If @n_bytes is 0 it returns %NULL. + * + * Returns: a pointer to the allocated memory + */ gpointer -g_malloc0 (gulong n_bytes) +g_malloc0 (gsize n_bytes) { - if (n_bytes) + if (G_LIKELY (n_bytes)) { gpointer mem; mem = glib_mem_vtable.calloc (1, n_bytes); + TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 1, 0)); if (mem) return mem; - g_error ("%s: failed to allocate %lu bytes", G_STRLOC, n_bytes); + g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes", + G_STRLOC, n_bytes); } + TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 1, 0)); + return NULL; } +/** + * g_realloc: + * @mem: (allow-none): the memory to reallocate + * @n_bytes: new size of the memory in bytes + * + * Reallocates the memory pointed to by @mem, so that it now has space for + * @n_bytes bytes of memory. It returns the new address of the memory, which may + * have been moved. @mem may be %NULL, in which case it's considered to + * have zero-length. @n_bytes may be 0, in which case %NULL will be returned + * and @mem will be freed unless it is %NULL. + * + * Returns: the new address of the allocated memory + */ gpointer g_realloc (gpointer mem, - gulong n_bytes) + gsize n_bytes) { - if (n_bytes) + gpointer newmem; + + if (G_LIKELY (n_bytes)) { - mem = glib_mem_vtable.realloc (mem, n_bytes); - if (mem) - return mem; + newmem = glib_mem_vtable.realloc (mem, n_bytes); + TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 0)); + if (newmem) + return newmem; - g_error ("%s: failed to allocate %lu bytes", G_STRLOC, n_bytes); + g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes", + G_STRLOC, n_bytes); } if (mem) glib_mem_vtable.free (mem); + TRACE (GLIB_MEM_REALLOC((void*) NULL, (void*)mem, 0, 0)); + return NULL; } +/** + * g_free: + * @mem: (allow-none): the memory to free + * + * Frees the memory pointed to by @mem. + * If @mem is %NULL it simply returns. + */ void g_free (gpointer mem) { - if (mem) + if (G_LIKELY (mem)) glib_mem_vtable.free (mem); + TRACE(GLIB_MEM_FREE((void*) mem)); +} + +/** + * g_clear_pointer: (skip) + * @pp: a pointer to a variable, struct member etc. holding a pointer + * @destroy: a function to which a gpointer can be passed, to destroy *@pp + * + * Clears a reference to a variable. + * + * @pp must not be %NULL. + * + * If the reference is %NULL then this function does nothing. + * Otherwise, the variable is destroyed using @destroy and the + * pointer is set to %NULL. + * + * A macro is also included that allows this function to be used without + * pointer casts. + * + * Since: 2.34 + **/ +#undef g_clear_pointer +void +g_clear_pointer (gpointer *pp, + GDestroyNotify destroy) +{ + gpointer _p; + + _p = *pp; + if (_p) + { + *pp = NULL; + destroy (_p); + } } +/** + * g_try_malloc: + * @n_bytes: number of bytes to allocate. + * + * Attempts to allocate @n_bytes, and returns %NULL on failure. + * Contrast with g_malloc(), which aborts the program on failure. + * + * Returns: the allocated memory, or %NULL. + */ gpointer -g_try_malloc (gulong n_bytes) +g_try_malloc (gsize n_bytes) { - if (n_bytes) - return glib_mem_vtable.try_malloc (n_bytes); + gpointer mem; + + if (G_LIKELY (n_bytes)) + mem = glib_mem_vtable.try_malloc (n_bytes); else - return NULL; + mem = NULL; + + TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 1)); + + return mem; } +/** + * g_try_malloc0: + * @n_bytes: number of bytes to allocate + * + * Attempts to allocate @n_bytes, initialized to 0's, and returns %NULL on + * failure. Contrast with g_malloc0(), which aborts the program on failure. + * + * Since: 2.8 + * Returns: the allocated memory, or %NULL + */ gpointer -g_try_malloc0 (gulong n_bytes) -{ +g_try_malloc0 (gsize n_bytes) +{ gpointer mem; - mem = g_try_malloc (n_bytes); - + if (G_LIKELY (n_bytes)) + mem = glib_mem_vtable.try_malloc (n_bytes); + else + mem = NULL; + if (mem) memset (mem, 0, n_bytes); return mem; } +/** + * g_try_realloc: + * @mem: (allow-none): previously-allocated memory, or %NULL. + * @n_bytes: number of bytes to allocate. + * + * Attempts to realloc @mem to a new size, @n_bytes, and returns %NULL + * on failure. Contrast with g_realloc(), which aborts the program + * on failure. If @mem is %NULL, behaves the same as g_try_malloc(). + * + * Returns: the allocated memory, or %NULL. + */ gpointer g_try_realloc (gpointer mem, - gulong n_bytes) + gsize n_bytes) { - if (n_bytes) - return glib_mem_vtable.try_realloc (mem, n_bytes); + gpointer newmem; - if (mem) - glib_mem_vtable.free (mem); + if (G_LIKELY (n_bytes)) + newmem = glib_mem_vtable.try_realloc (mem, n_bytes); + else + { + newmem = NULL; + if (mem) + glib_mem_vtable.free (mem); + } - return NULL; + TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 1)); + + return newmem; +} + + +#define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((b) > 0 && (a) > G_MAXSIZE / (b))) + +/** + * g_malloc_n: + * @n_blocks: the number of blocks to allocate + * @n_block_bytes: the size of each block in bytes + * + * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes, + * but care is taken to detect possible overflow during multiplication. + * + * Since: 2.24 + * Returns: a pointer to the allocated memory + */ +gpointer +g_malloc_n (gsize n_blocks, + gsize n_block_bytes) +{ + if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) + { + g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes", + G_STRLOC, n_blocks, n_block_bytes); + } + + return g_malloc (n_blocks * n_block_bytes); +} + +/** + * g_malloc0_n: + * @n_blocks: the number of blocks to allocate + * @n_block_bytes: the size of each block in bytes + * + * This function is similar to g_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes, + * but care is taken to detect possible overflow during multiplication. + * + * Since: 2.24 + * Returns: a pointer to the allocated memory + */ +gpointer +g_malloc0_n (gsize n_blocks, + gsize n_block_bytes) +{ + if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) + { + g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes", + G_STRLOC, n_blocks, n_block_bytes); + } + + return g_malloc0 (n_blocks * n_block_bytes); +} + +/** + * g_realloc_n: + * @mem: (allow-none): the memory to reallocate + * @n_blocks: the number of blocks to allocate + * @n_block_bytes: the size of each block in bytes + * + * This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes, + * but care is taken to detect possible overflow during multiplication. + * + * Since: 2.24 + * Returns: the new address of the allocated memory + */ +gpointer +g_realloc_n (gpointer mem, + gsize n_blocks, + gsize n_block_bytes) +{ + if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) + { + g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes", + G_STRLOC, n_blocks, n_block_bytes); + } + + return g_realloc (mem, n_blocks * n_block_bytes); +} + +/** + * g_try_malloc_n: + * @n_blocks: the number of blocks to allocate + * @n_block_bytes: the size of each block in bytes + * + * This function is similar to g_try_malloc(), allocating (@n_blocks * @n_block_bytes) bytes, + * but care is taken to detect possible overflow during multiplication. + * + * Since: 2.24 + * Returns: the allocated memory, or %NULL. + */ +gpointer +g_try_malloc_n (gsize n_blocks, + gsize n_block_bytes) +{ + if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) + return NULL; + + return g_try_malloc (n_blocks * n_block_bytes); +} + +/** + * g_try_malloc0_n: + * @n_blocks: the number of blocks to allocate + * @n_block_bytes: the size of each block in bytes + * + * This function is similar to g_try_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes, + * but care is taken to detect possible overflow during multiplication. + * + * Since: 2.24 + * Returns: the allocated memory, or %NULL + */ +gpointer +g_try_malloc0_n (gsize n_blocks, + gsize n_block_bytes) +{ + if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) + return NULL; + + return g_try_malloc0 (n_blocks * n_block_bytes); } +/** + * g_try_realloc_n: + * @mem: (allow-none): previously-allocated memory, or %NULL. + * @n_blocks: the number of blocks to allocate + * @n_block_bytes: the size of each block in bytes + * + * This function is similar to g_try_realloc(), allocating (@n_blocks * @n_block_bytes) bytes, + * but care is taken to detect possible overflow during multiplication. + * + * Since: 2.24 + * Returns: the allocated memory, or %NULL. + */ +gpointer +g_try_realloc_n (gpointer mem, + gsize n_blocks, + gsize n_block_bytes) +{ + if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) + return NULL; + + return g_try_realloc (mem, n_blocks * n_block_bytes); +} + + + static gpointer fallback_calloc (gsize n_blocks, gsize n_block_bytes) @@ -223,17 +465,17 @@ fallback_calloc (gsize n_blocks, static gboolean vtable_set = FALSE; /** - * g_mem_is_system_malloc + * g_mem_is_system_malloc: * * Checks whether the allocator used by g_malloc() is the system's * malloc implementation. If it returns %TRUE memory allocated with - * malloc() can be used interchangeable with memory allocated using g_malloc(). + * malloc() can be used interchangeable with memory allocated using g_malloc(). * This function is useful for avoiding an extra copy of allocated memory returned * by a non-GLib-based API. * * A different allocator can be set using g_mem_set_vtable(). * - * Return value: if %TRUE, malloc() and g_malloc() can be mixed. + * Returns: if %TRUE, malloc() and g_malloc() can be mixed. **/ gboolean g_mem_is_system_malloc (void) @@ -241,6 +483,22 @@ g_mem_is_system_malloc (void) return !vtable_set; } +/** + * g_mem_set_vtable: + * @vtable: table of memory allocation routines. + * + * Sets the #GMemVTable to use for memory allocation. You can use this + * to provide custom memory allocation routines. + * + * The @vtable only needs to provide malloc(), realloc(), and free() + * functions; GLib can provide default implementations of the others. + * The malloc() and realloc() implementations should return %NULL on + * failure, GLib will handle error-checking for you. @vtable is copied, + * so need not persist after this function has been called. + * + * Note that this function must be called before using any other GLib + * functions. + */ void g_mem_set_vtable (GMemVTable *vtable) { @@ -266,6 +524,14 @@ g_mem_set_vtable (GMemVTable *vtable) /* --- memory profiling and checking --- */ #ifdef G_DISABLE_CHECKS +/** + * glib_mem_profiler_table: + * + * A #GMemVTable containing profiling variants of the memory + * allocation functions. Use them together with g_mem_profile() + * in order to get information about the memory allocation pattern + * of your program. + */ GMemVTable *glib_mem_profiler_table = &glib_mem_vtable; void g_mem_profile (void) @@ -279,30 +545,26 @@ typedef enum { PROFILER_ZINIT = 4 } ProfilerJob; static guint *profile_data = NULL; -static gulong profile_allocs = 0; -static gulong profile_zinit = 0; -static gulong profile_frees = 0; -static GMutex *gmem_profile_mutex = NULL; -#ifdef G_ENABLE_DEBUG -static volatile gulong g_trap_free_size = 0; -static volatile gulong g_trap_realloc_size = 0; -static volatile gulong g_trap_malloc_size = 0; -#endif /* G_ENABLE_DEBUG */ +static gsize profile_allocs = 0; +static gsize profile_zinit = 0; +static gsize profile_frees = 0; +static GMutex gmem_profile_mutex; #define PROFILE_TABLE(f1,f2,f3) ( ( ((f3) << 2) | ((f2) << 1) | (f1) ) * (MEM_PROFILE_TABLE_SIZE + 1)) static void profiler_log (ProfilerJob job, - gulong n_bytes, + gsize n_bytes, gboolean success) { - g_mutex_lock (gmem_profile_mutex); + g_mutex_lock (&gmem_profile_mutex); if (!profile_data) { - profile_data = standard_malloc ((MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0])); + profile_data = calloc ((MEM_PROFILE_TABLE_SIZE + 1) * 8, + sizeof (profile_data[0])); if (!profile_data) /* memory system kiddin' me, eh? */ { - g_mutex_unlock (gmem_profile_mutex); + g_mutex_unlock (&gmem_profile_mutex); return; } } @@ -326,7 +588,7 @@ profiler_log (ProfilerJob job, else profile_frees += n_bytes; } - g_mutex_unlock (gmem_profile_mutex); + g_mutex_unlock (&gmem_profile_mutex); } static void @@ -365,15 +627,30 @@ profile_print_locked (guint *local_data, g_print (" --- none ---\n"); } +/** + * g_mem_profile: + * + * Outputs a summary of memory usage. + * + * It outputs the frequency of allocations of different sizes, + * the total number of bytes which have been allocated, + * the total number of bytes which have been freed, + * and the difference between the previous two values, i.e. the number of bytes + * still in use. + * + * Note that this function will not output anything unless you have + * previously installed the #glib_mem_profiler_table with g_mem_set_vtable(). + */ + void g_mem_profile (void) { - guint local_data[(MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0])]; - gulong local_allocs; - gulong local_zinit; - gulong local_frees; + guint local_data[(MEM_PROFILE_TABLE_SIZE + 1) * 8]; + gsize local_allocs; + gsize local_zinit; + gsize local_frees; - g_mutex_lock (gmem_profile_mutex); + g_mutex_lock (&gmem_profile_mutex); local_allocs = profile_allocs; local_zinit = profile_zinit; @@ -381,20 +658,23 @@ g_mem_profile (void) if (!profile_data) { - g_mutex_unlock (gmem_profile_mutex); + g_mutex_unlock (&gmem_profile_mutex); return; } memcpy (local_data, profile_data, (MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0])); - g_mutex_unlock (gmem_profile_mutex); + g_mutex_unlock (&gmem_profile_mutex); g_print ("GLib Memory statistics (successful operations):\n"); profile_print_locked (local_data, TRUE); g_print ("GLib Memory statistics (failing operations):\n"); profile_print_locked (local_data, FALSE); - g_print ("Total bytes: allocated=%lu, zero-initialized=%lu (%.2f%%), freed=%lu (%.2f%%), remaining=%lu\n", + g_print ("Total bytes: allocated=%"G_GSIZE_FORMAT", " + "zero-initialized=%"G_GSIZE_FORMAT" (%.2f%%), " + "freed=%"G_GSIZE_FORMAT" (%.2f%%), " + "remaining=%"G_GSIZE_FORMAT"\n", local_allocs, local_zinit, ((gdouble) local_zinit) / local_allocs * 100.0, @@ -406,14 +686,9 @@ g_mem_profile (void) static gpointer profiler_try_malloc (gsize n_bytes) { - gulong *p; - -#ifdef G_ENABLE_DEBUG - if (g_trap_malloc_size == n_bytes) - G_BREAKPOINT (); -#endif /* G_ENABLE_DEBUG */ + gsize *p; - p = standard_malloc (sizeof (gulong) * 2 + n_bytes); + p = malloc (sizeof (gsize) * 2 + n_bytes); if (p) { @@ -444,14 +719,9 @@ profiler_calloc (gsize n_blocks, gsize n_block_bytes) { gsize l = n_blocks * n_block_bytes; - gulong *p; + gsize *p; -#ifdef G_ENABLE_DEBUG - if (g_trap_malloc_size == l) - G_BREAKPOINT (); -#endif /* G_ENABLE_DEBUG */ - - p = standard_calloc (1, sizeof (gulong) * 2 + l); + p = calloc (1, sizeof (gsize) * 2 + l); if (p) { @@ -472,29 +742,25 @@ profiler_calloc (gsize n_blocks, static void profiler_free (gpointer mem) { - gulong *p = mem; + gsize *p = mem; p -= 2; if (p[0]) /* free count */ { - g_warning ("free(%p): memory has been freed %lu times already", p + 2, p[0]); + g_warning ("free(%p): memory has been freed %"G_GSIZE_FORMAT" times already", + p + 2, p[0]); profiler_log (PROFILER_FREE, p[1], /* length */ FALSE); } else { -#ifdef G_ENABLE_DEBUG - if (g_trap_free_size == p[1]) - G_BREAKPOINT (); -#endif /* G_ENABLE_DEBUG */ - profiler_log (PROFILER_FREE, p[1], /* length */ TRUE); memset (p + 2, 0xaa, p[1]); - /* for all those that miss standard_free (p); in this place, yes, + /* for all those that miss free (p); in this place, yes, * we do leak all memory when profiling, and that is intentional * to catch double frees. patch submissions are futile. */ @@ -506,25 +772,22 @@ static gpointer profiler_try_realloc (gpointer mem, gsize n_bytes) { - gulong *p = mem; + gsize *p = mem; p -= 2; - -#ifdef G_ENABLE_DEBUG - if (g_trap_realloc_size == n_bytes) - G_BREAKPOINT (); -#endif /* G_ENABLE_DEBUG */ if (mem && p[0]) /* free count */ { - g_warning ("realloc(%p, %lu): memory has been freed %lu times already", p + 2, (gulong)n_bytes, p[0]); + g_warning ("realloc(%p, %"G_GSIZE_FORMAT"): " + "memory has been freed %"G_GSIZE_FORMAT" times already", + p + 2, (gsize) n_bytes, p[0]); profiler_log (PROFILER_ALLOC | PROFILER_RELOC, n_bytes, FALSE); return NULL; } else { - p = standard_realloc (mem ? p : NULL, sizeof (gulong) * 2 + n_bytes); + p = realloc (mem ? p : NULL, sizeof (gsize) * 2 + n_bytes); if (p) { @@ -565,106 +828,3 @@ static GMemVTable profiler_table = { GMemVTable *glib_mem_profiler_table = &profiler_table; #endif /* !G_DISABLE_CHECKS */ - -/* --- MemChunks --- */ -#ifndef G_ALLOC_AND_FREE -typedef struct _GAllocator GAllocator; -typedef struct _GMemChunk GMemChunk; -#define G_ALLOC_ONLY 1 -#define G_ALLOC_AND_FREE 2 -#endif - -struct _GMemChunk { - guint alloc_size; /* the size of an atom */ -}; - -GMemChunk* -g_mem_chunk_new (const gchar *name, - gint atom_size, - gulong area_size, - gint type) -{ - GMemChunk *mem_chunk; - g_return_val_if_fail (atom_size > 0, NULL); - - mem_chunk = g_slice_new (GMemChunk); - mem_chunk->alloc_size = atom_size; - return mem_chunk; -} - -void -g_mem_chunk_destroy (GMemChunk *mem_chunk) -{ - g_return_if_fail (mem_chunk != NULL); - - g_slice_free (GMemChunk, mem_chunk); -} - -gpointer -g_mem_chunk_alloc (GMemChunk *mem_chunk) -{ - g_return_val_if_fail (mem_chunk != NULL, NULL); - - return g_slice_alloc (mem_chunk->alloc_size); -} - -gpointer -g_mem_chunk_alloc0 (GMemChunk *mem_chunk) -{ - g_return_val_if_fail (mem_chunk != NULL, NULL); - - return g_slice_alloc0 (mem_chunk->alloc_size); -} - -void -g_mem_chunk_free (GMemChunk *mem_chunk, - gpointer mem) -{ - g_return_if_fail (mem_chunk != NULL); - - g_slice_free1 (mem_chunk->alloc_size, mem); -} - -void g_mem_chunk_clean (GMemChunk *mem_chunk) {} -void g_mem_chunk_reset (GMemChunk *mem_chunk) {} -void g_mem_chunk_print (GMemChunk *mem_chunk) {} -void g_mem_chunk_info (void) {} -void g_blow_chunks (void) {} - -GAllocator* -g_allocator_new (const gchar *name, - guint n_preallocs) -{ - static struct _GAllocator { - gchar *name; - guint16 n_preallocs; - guint is_unused : 1; - guint type : 4; - GAllocator *last; - GMemChunk *mem_chunk; - gpointer free_list; - } dummy = { - "GAllocator is deprecated", 1, TRUE, 0, NULL, NULL, NULL, - }; - /* some (broken) GAllocator uses depend on non-NULL allocators */ - return (void*) &dummy; -} - -void -g_allocator_free (GAllocator *allocator) -{ -} - -void -_g_mem_thread_init_noprivate_nomessage (void) -{ - /* we may only create mutexes here, locking/unlocking itself - * does not yet work. - */ -#ifndef G_DISABLE_CHECKS - gmem_profile_mutex = g_mutex_new (); -#endif -} - -#define __G_MEM_C__ -#include "galiasdef.c"