⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gmem.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * 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. *//* * Modified by the GLib Team and others 1997-2000.  See the AUTHORS * file for a list of people on the GLib Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GLib at ftp://ftp.gtk.org/pub/gtk/.  *//*  * MT safe */#ifdef HAVE_CONFIG_H#include "glibconfig.h"#endif#include <stdlib.h>#include <string.h>#include <signal.h>#include "glib.h"/* notes on macros: * having DISABLE_MEM_POOLS defined, disables mem_chunks alltogether, their * allocations are performed through ordinary g_malloc/g_free. * 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. */#define MEM_PROFILE_TABLE_SIZE 4096#define MEM_AREA_SIZE 4L#ifdef	G_DISABLE_CHECKS#  define ENTER_MEM_CHUNK_ROUTINE()#  define LEAVE_MEM_CHUNK_ROUTINE()#  define IN_MEM_CHUNK_ROUTINE()	FALSE#else	/* !G_DISABLE_CHECKS */static GPrivate* mem_chunk_recursion = NULL;#  define MEM_CHUNK_ROUTINE_COUNT()	GPOINTER_TO_UINT (g_private_get (mem_chunk_recursion))#  define ENTER_MEM_CHUNK_ROUTINE()	g_private_set (mem_chunk_recursion, GUINT_TO_POINTER (MEM_CHUNK_ROUTINE_COUNT () + 1))#  define LEAVE_MEM_CHUNK_ROUTINE()	g_private_set (mem_chunk_recursion, GUINT_TO_POINTER (MEM_CHUNK_ROUTINE_COUNT () - 1))#endif	/* !G_DISABLE_CHECKS */#ifndef	REALLOC_0_WORKSstatic gpointerstandard_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 gpointerstandard_malloc (gsize n_bytes){  return malloc (n_bytes);}#  ifdef REALLOC_0_WORKSstatic gpointerstandard_realloc (gpointer mem,		  gsize    n_bytes){  return realloc (mem, n_bytes);}#  endif /* REALLOC_0_WORKS */static voidstandard_free (gpointer mem){  free (mem);}static gpointerstandard_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,};/* --- functions --- */gpointerg_malloc (gulong n_bytes){  if (n_bytes)    {      gpointer mem;      mem = glib_mem_vtable.malloc (n_bytes);      if (mem)	return mem;      g_error ("%s: failed to allocate %lu bytes", G_STRLOC, n_bytes);    }  return NULL;}gpointerg_malloc0 (gulong n_bytes){  if (n_bytes)    {      gpointer mem;      mem = glib_mem_vtable.calloc (1, n_bytes);      if (mem)	return mem;      g_error ("%s: failed to allocate %lu bytes", G_STRLOC, n_bytes);    }  return NULL;}gpointerg_realloc (gpointer mem,	   gulong   n_bytes){  if (n_bytes)    {      mem = glib_mem_vtable.realloc (mem, n_bytes);      if (mem)	return mem;      g_error ("%s: failed to allocate %lu bytes", G_STRLOC, n_bytes);    }  if (mem)    glib_mem_vtable.free (mem);  return NULL;}voidg_free (gpointer mem){  if (mem)    glib_mem_vtable.free (mem);}gpointerg_try_malloc (gulong n_bytes){  if (n_bytes)    return glib_mem_vtable.try_malloc (n_bytes);  else    return NULL;}gpointerg_try_realloc (gpointer mem,	       gulong   n_bytes){  if (n_bytes)    return glib_mem_vtable.try_realloc (mem, n_bytes);  if (mem)    glib_mem_vtable.free (mem);  return NULL;}static gpointerfallback_calloc (gsize n_blocks,		 gsize n_block_bytes){  gsize l = n_blocks * n_block_bytes;  gpointer mem = glib_mem_vtable.malloc (l);  if (mem)    memset (mem, 0, l);  return mem;}static gboolean vtable_set = FALSE;/** * 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 * <function>malloc()</function> 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, <function>malloc()</function> and g_malloc() can be mixed. **/gbooleang_mem_is_system_malloc (void){  return !vtable_set;}voidg_mem_set_vtable (GMemVTable *vtable){  if (!vtable_set)    {      vtable_set = TRUE;      if (vtable->malloc && vtable->realloc && vtable->free)	{	  glib_mem_vtable.malloc = vtable->malloc;	  glib_mem_vtable.realloc = vtable->realloc;	  glib_mem_vtable.free = vtable->free;	  glib_mem_vtable.calloc = vtable->calloc ? vtable->calloc : fallback_calloc;	  glib_mem_vtable.try_malloc = vtable->try_malloc ? vtable->try_malloc : glib_mem_vtable.malloc;	  glib_mem_vtable.try_realloc = vtable->try_realloc ? vtable->try_realloc : glib_mem_vtable.realloc;	}      else	g_warning (G_STRLOC ": memory allocation vtable lacks one of malloc(), realloc() or free()");    }  else    g_warning (G_STRLOC ": memory allocation vtable can only be set once at startup");}/* --- memory profiling and checking --- */#ifdef	G_DISABLE_CHECKSGMemVTable *glib_mem_profiler_table = &glib_mem_vtable;voidg_mem_profile (void){}#else	/* !G_DISABLE_CHECKS */typedef enum {  PROFILER_FREE		= 0,  PROFILER_ALLOC	= 1,  PROFILER_RELOC	= 2,  PROFILER_ZINIT	= 4} ProfilerJob;static guint *profile_data = NULL;static gulong profile_allocs = 0;static gulong profile_mc_allocs = 0;static gulong profile_zinit = 0;static gulong profile_frees = 0;static gulong profile_mc_frees = 0;static GMutex *g_profile_mutex = NULL;#ifdef  G_ENABLE_DEBUGstatic 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 */#define	PROFILE_TABLE(f1,f2,f3)   ( ( ((f3) << 2) | ((f2) << 1) | (f1) ) * (MEM_PROFILE_TABLE_SIZE + 1))static voidprofiler_log (ProfilerJob job,	      gulong      n_bytes,	      gboolean    success){  g_mutex_lock (g_profile_mutex);  if (!profile_data)    {      profile_data = standard_malloc ((MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0]));      if (!profile_data)	/* memory system kiddin' me, eh? */	{	  g_mutex_unlock (g_profile_mutex);	  return;	}    }  if (MEM_CHUNK_ROUTINE_COUNT () == 0)    {      if (n_bytes < MEM_PROFILE_TABLE_SIZE)	profile_data[n_bytes + PROFILE_TABLE ((job & PROFILER_ALLOC) != 0,					      (job & PROFILER_RELOC) != 0,					      success != 0)] += 1;      else	profile_data[MEM_PROFILE_TABLE_SIZE + PROFILE_TABLE ((job & PROFILER_ALLOC) != 0,							     (job & PROFILER_RELOC) != 0,							     success != 0)] += 1;      if (success)	{	  if (job & PROFILER_ALLOC)	    {	      profile_allocs += n_bytes;	      if (job & PROFILER_ZINIT)		profile_zinit += n_bytes;	    }	  else	    profile_frees += n_bytes;	}    }  else if (success)    {      if (job & PROFILER_ALLOC)	profile_mc_allocs += n_bytes;      else	profile_mc_frees += n_bytes;    }  g_mutex_unlock (g_profile_mutex);}static voidprofile_print_locked (guint   *local_data,		      gboolean success){  gboolean need_header = TRUE;  guint i;  for (i = 0; i <= MEM_PROFILE_TABLE_SIZE; i++)    {      glong t_malloc = local_data[i + PROFILE_TABLE (1, 0, success)];      glong t_realloc = local_data[i + PROFILE_TABLE (1, 1, success)];      glong t_free = local_data[i + PROFILE_TABLE (0, 0, success)];      glong t_refree = local_data[i + PROFILE_TABLE (0, 1, success)];            if (!t_malloc && !t_realloc && !t_free && !t_refree)	continue;      else if (need_header)	{	  need_header = FALSE;	  g_print (" blocks of | allocated  | freed      | allocated  | freed      | n_bytes   \n");	  g_print ("  n_bytes  | n_times by | n_times by | n_times by | n_times by | remaining \n");	  g_print ("           | malloc()   | free()     | realloc()  | realloc()  |           \n");	  g_print ("===========|============|============|============|============|===========\n");	}      if (i < MEM_PROFILE_TABLE_SIZE)	g_print ("%10u | %10ld | %10ld | %10ld | %10ld |%+11ld\n",		 i, t_malloc, t_free, t_realloc, t_refree,		 (t_malloc - t_free + t_realloc - t_refree) * i);      else if (i >= MEM_PROFILE_TABLE_SIZE)	g_print ("   >%6u | %10ld | %10ld | %10ld | %10ld |        ***\n",		 i, t_malloc, t_free, t_realloc, t_refree);    }  if (need_header)    g_print (" --- none ---\n");}voidg_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;  gulong local_mc_allocs;  gulong local_mc_frees;  g_mutex_lock (g_profile_mutex);  local_allocs = profile_allocs;  local_zinit = profile_zinit;  local_frees = profile_frees;  local_mc_allocs = profile_mc_allocs;  local_mc_frees = profile_mc_frees;  if (!profile_data)    {      g_mutex_unlock (g_profile_mutex);      return;    }  memcpy (local_data, profile_data, 	  (MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0]));    g_mutex_unlock (g_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",	   local_allocs,	   local_zinit,	   ((gdouble) local_zinit) / local_allocs * 100.0,	   local_frees,	   ((gdouble) local_frees) / local_allocs * 100.0,	   local_allocs - local_frees);  g_print ("MemChunk bytes: allocated=%lu, freed=%lu (%.2f%%), remaining=%lu\n",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -