os/ossrv/glib/tsrc/BC/tests/memchunks.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* GLIB - Library of useful routines for C programming
sl@0
     2
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
sl@0
     3
 *
sl@0
     4
 * This library is free software; you can redistribute it and/or
sl@0
     5
 * modify it under the terms of the GNU Lesser General Public
sl@0
     6
 * License as published by the Free Software Foundation; either
sl@0
     7
 * version 2 of the License, or (at your option) any later version.
sl@0
     8
 *
sl@0
     9
 * This library is distributed in the hope that it will be useful,
sl@0
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
sl@0
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
sl@0
    12
 * Lesser General Public License for more details.
sl@0
    13
 *
sl@0
    14
 * You should have received a copy of the GNU Lesser General Public
sl@0
    15
 * License along with this library; if not, write to the
sl@0
    16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
sl@0
    17
 * Boston, MA 02111-1307, USA.
sl@0
    18
 */
sl@0
    19
sl@0
    20
/*
sl@0
    21
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
sl@0
    22
 * file for a list of people on the GLib Team.  See the ChangeLog
sl@0
    23
 * files for a list of changes.  These files are distributed with
sl@0
    24
 * GLib at ftp://ftp.gtk.org/pub/gtk/. 
sl@0
    25
 */
sl@0
    26
sl@0
    27
/* 
sl@0
    28
 * MT safe
sl@0
    29
 */
sl@0
    30
sl@0
    31
#include "config.h"
sl@0
    32
sl@0
    33
#include <stdlib.h>
sl@0
    34
#include <string.h>
sl@0
    35
#include <signal.h>
sl@0
    36
sl@0
    37
#include "glib.h"
sl@0
    38
sl@0
    39
/* notes on macros:
sl@0
    40
 * if ENABLE_GC_FRIENDLY is defined, freed memory should be 0-wiped.
sl@0
    41
 */
sl@0
    42
sl@0
    43
#define MEM_PROFILE_TABLE_SIZE 4096
sl@0
    44
sl@0
    45
#define MEM_AREA_SIZE 4L
sl@0
    46
sl@0
    47
static guint mem_chunk_recursion = 0;
sl@0
    48
#  define MEM_CHUNK_ROUTINE_COUNT()	(mem_chunk_recursion)
sl@0
    49
#  define ENTER_MEM_CHUNK_ROUTINE()	(mem_chunk_recursion = MEM_CHUNK_ROUTINE_COUNT () + 1)
sl@0
    50
#  define LEAVE_MEM_CHUNK_ROUTINE()	(mem_chunk_recursion = MEM_CHUNK_ROUTINE_COUNT () - 1)
sl@0
    51
sl@0
    52
/* --- old memchunk prototypes --- */
sl@0
    53
void            old_mem_chunks_init     (void);
sl@0
    54
GMemChunk*      old_mem_chunk_new       (const gchar  *name,
sl@0
    55
                                         gint          atom_size,
sl@0
    56
                                         gulong        area_size,
sl@0
    57
                                         gint          type);
sl@0
    58
void            old_mem_chunk_destroy   (GMemChunk *mem_chunk);
sl@0
    59
gpointer        old_mem_chunk_alloc     (GMemChunk *mem_chunk);
sl@0
    60
gpointer        old_mem_chunk_alloc0    (GMemChunk *mem_chunk);
sl@0
    61
void            old_mem_chunk_free      (GMemChunk *mem_chunk,
sl@0
    62
                                         gpointer   mem);
sl@0
    63
void            old_mem_chunk_clean     (GMemChunk *mem_chunk);
sl@0
    64
void            old_mem_chunk_reset     (GMemChunk *mem_chunk);
sl@0
    65
void            old_mem_chunk_print     (GMemChunk *mem_chunk);
sl@0
    66
void            old_mem_chunk_info      (void);
sl@0
    67
sl@0
    68
sl@0
    69
/* --- MemChunks --- */
sl@0
    70
#ifndef G_ALLOC_AND_FREE
sl@0
    71
typedef struct _GAllocator GAllocator;
sl@0
    72
typedef struct _GMemChunk  GMemChunk;
sl@0
    73
#define G_ALLOC_ONLY	  1
sl@0
    74
#define G_ALLOC_AND_FREE  2
sl@0
    75
#endif
sl@0
    76
sl@0
    77
typedef struct _GFreeAtom      GFreeAtom;
sl@0
    78
typedef struct _GMemArea       GMemArea;
sl@0
    79
sl@0
    80
struct _GFreeAtom
sl@0
    81
{
sl@0
    82
  GFreeAtom *next;
sl@0
    83
};
sl@0
    84
sl@0
    85
struct _GMemArea
sl@0
    86
{
sl@0
    87
  GMemArea *next;            /* the next mem area */
sl@0
    88
  GMemArea *prev;            /* the previous mem area */
sl@0
    89
  gulong index;              /* the current index into the "mem" array */
sl@0
    90
  gulong free;               /* the number of free bytes in this mem area */
sl@0
    91
  gulong allocated;          /* the number of atoms allocated from this area */
sl@0
    92
  gulong mark;               /* is this mem area marked for deletion */
sl@0
    93
  gchar mem[MEM_AREA_SIZE];  /* the mem array from which atoms get allocated
sl@0
    94
			      * the actual size of this array is determined by
sl@0
    95
			      *  the mem chunk "area_size". ANSI says that it
sl@0
    96
			      *  must be declared to be the maximum size it
sl@0
    97
			      *  can possibly be (even though the actual size
sl@0
    98
			      *  may be less).
sl@0
    99
			      */
sl@0
   100
};
sl@0
   101
sl@0
   102
struct _GMemChunk
sl@0
   103
{
sl@0
   104
  const gchar *name;         /* name of this MemChunk...used for debugging output */
sl@0
   105
  gint type;                 /* the type of MemChunk: ALLOC_ONLY or ALLOC_AND_FREE */
sl@0
   106
  gint num_mem_areas;        /* the number of memory areas */
sl@0
   107
  gint num_marked_areas;     /* the number of areas marked for deletion */
sl@0
   108
  guint atom_size;           /* the size of an atom */
sl@0
   109
  gulong area_size;          /* the size of a memory area */
sl@0
   110
  GMemArea *mem_area;        /* the current memory area */
sl@0
   111
  GMemArea *mem_areas;       /* a list of all the mem areas owned by this chunk */
sl@0
   112
  GMemArea *free_mem_area;   /* the free area...which is about to be destroyed */
sl@0
   113
  GFreeAtom *free_atoms;     /* the free atoms list */
sl@0
   114
  GTree *mem_tree;           /* tree of mem areas sorted by memory address */
sl@0
   115
  GMemChunk *next;           /* pointer to the next chunk */
sl@0
   116
  GMemChunk *prev;           /* pointer to the previous chunk */
sl@0
   117
};
sl@0
   118
sl@0
   119
sl@0
   120
static gulong old_mem_chunk_compute_size (gulong    size,
sl@0
   121
                                          gulong    min_size) G_GNUC_CONST;
sl@0
   122
static gint   old_mem_chunk_area_compare (GMemArea *a,
sl@0
   123
                                          GMemArea *b);
sl@0
   124
static gint   old_mem_chunk_area_search  (GMemArea *a,
sl@0
   125
                                          gchar    *addr);
sl@0
   126
sl@0
   127
/* here we can't use StaticMutexes, as they depend upon a working
sl@0
   128
 * g_malloc, the same holds true for StaticPrivate
sl@0
   129
 */
sl@0
   130
static GMutex        *mem_chunks_lock = NULL;
sl@0
   131
static GMemChunk     *mem_chunks = NULL;
sl@0
   132
sl@0
   133
void
sl@0
   134
old_mem_chunks_init (void)
sl@0
   135
{
sl@0
   136
  mem_chunks_lock = g_mutex_new ();
sl@0
   137
}
sl@0
   138
sl@0
   139
GMemChunk*
sl@0
   140
old_mem_chunk_new (const gchar  *name,
sl@0
   141
                   gint          atom_size,
sl@0
   142
                   gulong        area_size,
sl@0
   143
                   gint          type)
sl@0
   144
{
sl@0
   145
  GMemChunk *mem_chunk;
sl@0
   146
  gulong rarea_size;
sl@0
   147
  
sl@0
   148
  g_return_val_if_fail (atom_size > 0, NULL);
sl@0
   149
  g_return_val_if_fail (area_size >= atom_size, NULL);
sl@0
   150
  
sl@0
   151
  ENTER_MEM_CHUNK_ROUTINE ();
sl@0
   152
  
sl@0
   153
  area_size = (area_size + atom_size - 1) / atom_size;
sl@0
   154
  area_size *= atom_size;
sl@0
   155
  
sl@0
   156
  mem_chunk = g_new (GMemChunk, 1);
sl@0
   157
  mem_chunk->name = name;
sl@0
   158
  mem_chunk->type = type;
sl@0
   159
  mem_chunk->num_mem_areas = 0;
sl@0
   160
  mem_chunk->num_marked_areas = 0;
sl@0
   161
  mem_chunk->mem_area = NULL;
sl@0
   162
  mem_chunk->free_mem_area = NULL;
sl@0
   163
  mem_chunk->free_atoms = NULL;
sl@0
   164
  mem_chunk->mem_tree = NULL;
sl@0
   165
  mem_chunk->mem_areas = NULL;
sl@0
   166
  mem_chunk->atom_size = atom_size;
sl@0
   167
  
sl@0
   168
  if (mem_chunk->type == G_ALLOC_AND_FREE)
sl@0
   169
    mem_chunk->mem_tree = g_tree_new ((GCompareFunc) old_mem_chunk_area_compare);
sl@0
   170
  
sl@0
   171
  if (mem_chunk->atom_size % G_MEM_ALIGN)
sl@0
   172
    mem_chunk->atom_size += G_MEM_ALIGN - (mem_chunk->atom_size % G_MEM_ALIGN);
sl@0
   173
  
sl@0
   174
  rarea_size = area_size + sizeof (GMemArea) - MEM_AREA_SIZE;
sl@0
   175
  rarea_size = old_mem_chunk_compute_size (rarea_size, atom_size + sizeof (GMemArea) - MEM_AREA_SIZE);
sl@0
   176
  mem_chunk->area_size = rarea_size - (sizeof (GMemArea) - MEM_AREA_SIZE);
sl@0
   177
  
sl@0
   178
  g_mutex_lock (mem_chunks_lock);
sl@0
   179
  mem_chunk->next = mem_chunks;
sl@0
   180
  mem_chunk->prev = NULL;
sl@0
   181
  if (mem_chunks)
sl@0
   182
    mem_chunks->prev = mem_chunk;
sl@0
   183
  mem_chunks = mem_chunk;
sl@0
   184
  g_mutex_unlock (mem_chunks_lock);
sl@0
   185
  
sl@0
   186
  LEAVE_MEM_CHUNK_ROUTINE ();
sl@0
   187
  
sl@0
   188
  return mem_chunk;
sl@0
   189
}
sl@0
   190
sl@0
   191
void
sl@0
   192
old_mem_chunk_destroy (GMemChunk *mem_chunk)
sl@0
   193
{
sl@0
   194
  GMemArea *mem_areas;
sl@0
   195
  GMemArea *temp_area;
sl@0
   196
  
sl@0
   197
  g_return_if_fail (mem_chunk != NULL);
sl@0
   198
  
sl@0
   199
  ENTER_MEM_CHUNK_ROUTINE ();
sl@0
   200
  
sl@0
   201
  mem_areas = mem_chunk->mem_areas;
sl@0
   202
  while (mem_areas)
sl@0
   203
    {
sl@0
   204
      temp_area = mem_areas;
sl@0
   205
      mem_areas = mem_areas->next;
sl@0
   206
      g_free (temp_area);
sl@0
   207
    }
sl@0
   208
  
sl@0
   209
  g_mutex_lock (mem_chunks_lock);
sl@0
   210
  if (mem_chunk->next)
sl@0
   211
    mem_chunk->next->prev = mem_chunk->prev;
sl@0
   212
  if (mem_chunk->prev)
sl@0
   213
    mem_chunk->prev->next = mem_chunk->next;
sl@0
   214
  
sl@0
   215
  if (mem_chunk == mem_chunks)
sl@0
   216
    mem_chunks = mem_chunks->next;
sl@0
   217
  g_mutex_unlock (mem_chunks_lock);
sl@0
   218
  
sl@0
   219
  if (mem_chunk->type == G_ALLOC_AND_FREE)
sl@0
   220
    g_tree_destroy (mem_chunk->mem_tree);  
sl@0
   221
  
sl@0
   222
  g_free (mem_chunk);
sl@0
   223
  
sl@0
   224
  LEAVE_MEM_CHUNK_ROUTINE ();
sl@0
   225
}
sl@0
   226
sl@0
   227
gpointer
sl@0
   228
old_mem_chunk_alloc (GMemChunk *mem_chunk)
sl@0
   229
{
sl@0
   230
  GMemArea *temp_area;
sl@0
   231
  gpointer mem;
sl@0
   232
  
sl@0
   233
  ENTER_MEM_CHUNK_ROUTINE ();
sl@0
   234
  
sl@0
   235
  g_return_val_if_fail (mem_chunk != NULL, NULL);
sl@0
   236
  
sl@0
   237
  while (mem_chunk->free_atoms)
sl@0
   238
    {
sl@0
   239
      /* Get the first piece of memory on the "free_atoms" list.
sl@0
   240
       * We can go ahead and destroy the list node we used to keep
sl@0
   241
       *  track of it with and to update the "free_atoms" list to
sl@0
   242
       *  point to its next element.
sl@0
   243
       */
sl@0
   244
      mem = mem_chunk->free_atoms;
sl@0
   245
      mem_chunk->free_atoms = mem_chunk->free_atoms->next;
sl@0
   246
      
sl@0
   247
      /* Determine which area this piece of memory is allocated from */
sl@0
   248
      temp_area = g_tree_search (mem_chunk->mem_tree,
sl@0
   249
				 (GCompareFunc) old_mem_chunk_area_search,
sl@0
   250
				 mem);
sl@0
   251
      
sl@0
   252
      /* If the area has been marked, then it is being destroyed.
sl@0
   253
       *  (ie marked to be destroyed).
sl@0
   254
       * We check to see if all of the segments on the free list that
sl@0
   255
       *  reference this area have been removed. This occurs when
sl@0
   256
       *  the ammount of free memory is less than the allocatable size.
sl@0
   257
       * If the chunk should be freed, then we place it in the "free_mem_area".
sl@0
   258
       * This is so we make sure not to free the mem area here and then
sl@0
   259
       *  allocate it again a few lines down.
sl@0
   260
       * If we don't allocate a chunk a few lines down then the "free_mem_area"
sl@0
   261
       *  will be freed.
sl@0
   262
       * If there is already a "free_mem_area" then we'll just free this mem area.
sl@0
   263
       */
sl@0
   264
      if (temp_area->mark)
sl@0
   265
        {
sl@0
   266
          /* Update the "free" memory available in that area */
sl@0
   267
          temp_area->free += mem_chunk->atom_size;
sl@0
   268
	  
sl@0
   269
          if (temp_area->free == mem_chunk->area_size)
sl@0
   270
            {
sl@0
   271
              if (temp_area == mem_chunk->mem_area)
sl@0
   272
                mem_chunk->mem_area = NULL;
sl@0
   273
	      
sl@0
   274
              if (mem_chunk->free_mem_area)
sl@0
   275
                {
sl@0
   276
                  mem_chunk->num_mem_areas -= 1;
sl@0
   277
		  
sl@0
   278
                  if (temp_area->next)
sl@0
   279
                    temp_area->next->prev = temp_area->prev;
sl@0
   280
                  if (temp_area->prev)
sl@0
   281
                    temp_area->prev->next = temp_area->next;
sl@0
   282
                  if (temp_area == mem_chunk->mem_areas)
sl@0
   283
                    mem_chunk->mem_areas = mem_chunk->mem_areas->next;
sl@0
   284
		  
sl@0
   285
		  if (mem_chunk->type == G_ALLOC_AND_FREE)
sl@0
   286
		    g_tree_remove (mem_chunk->mem_tree, temp_area);
sl@0
   287
                  g_free (temp_area);
sl@0
   288
                }
sl@0
   289
              else
sl@0
   290
                mem_chunk->free_mem_area = temp_area;
sl@0
   291
	      
sl@0
   292
	      mem_chunk->num_marked_areas -= 1;
sl@0
   293
	    }
sl@0
   294
	}
sl@0
   295
      else
sl@0
   296
        {
sl@0
   297
          /* Update the number of allocated atoms count.
sl@0
   298
	   */
sl@0
   299
          temp_area->allocated += 1;
sl@0
   300
	  
sl@0
   301
          /* The area wasn't marked...return the memory
sl@0
   302
	   */
sl@0
   303
	  goto outa_here;
sl@0
   304
        }
sl@0
   305
    }
sl@0
   306
  
sl@0
   307
  /* If there isn't a current mem area or the current mem area is out of space
sl@0
   308
   *  then allocate a new mem area. We'll first check and see if we can use
sl@0
   309
   *  the "free_mem_area". Otherwise we'll just malloc the mem area.
sl@0
   310
   */
sl@0
   311
  if ((!mem_chunk->mem_area) ||
sl@0
   312
      ((mem_chunk->mem_area->index + mem_chunk->atom_size) > mem_chunk->area_size))
sl@0
   313
    {
sl@0
   314
      if (mem_chunk->free_mem_area)
sl@0
   315
        {
sl@0
   316
          mem_chunk->mem_area = mem_chunk->free_mem_area;
sl@0
   317
	  mem_chunk->free_mem_area = NULL;
sl@0
   318
        }
sl@0
   319
      else
sl@0
   320
        {
sl@0
   321
#ifdef ENABLE_GC_FRIENDLY
sl@0
   322
	  mem_chunk->mem_area = (GMemArea*) g_malloc0 (sizeof (GMemArea) -
sl@0
   323
						       MEM_AREA_SIZE +
sl@0
   324
						       mem_chunk->area_size); 
sl@0
   325
#else /* !ENABLE_GC_FRIENDLY */
sl@0
   326
	  mem_chunk->mem_area = (GMemArea*) g_malloc (sizeof (GMemArea) -
sl@0
   327
						      MEM_AREA_SIZE +
sl@0
   328
						      mem_chunk->area_size);
sl@0
   329
#endif /* ENABLE_GC_FRIENDLY */
sl@0
   330
	  
sl@0
   331
	  mem_chunk->num_mem_areas += 1;
sl@0
   332
	  mem_chunk->mem_area->next = mem_chunk->mem_areas;
sl@0
   333
	  mem_chunk->mem_area->prev = NULL;
sl@0
   334
	  
sl@0
   335
	  if (mem_chunk->mem_areas)
sl@0
   336
	    mem_chunk->mem_areas->prev = mem_chunk->mem_area;
sl@0
   337
	  mem_chunk->mem_areas = mem_chunk->mem_area;
sl@0
   338
	  
sl@0
   339
	  if (mem_chunk->type == G_ALLOC_AND_FREE)
sl@0
   340
	    g_tree_insert (mem_chunk->mem_tree, mem_chunk->mem_area, mem_chunk->mem_area);
sl@0
   341
        }
sl@0
   342
      
sl@0
   343
      mem_chunk->mem_area->index = 0;
sl@0
   344
      mem_chunk->mem_area->free = mem_chunk->area_size;
sl@0
   345
      mem_chunk->mem_area->allocated = 0;
sl@0
   346
      mem_chunk->mem_area->mark = 0;
sl@0
   347
    }
sl@0
   348
  
sl@0
   349
  /* Get the memory and modify the state variables appropriately.
sl@0
   350
   */
sl@0
   351
  mem = (gpointer) &mem_chunk->mem_area->mem[mem_chunk->mem_area->index];
sl@0
   352
  mem_chunk->mem_area->index += mem_chunk->atom_size;
sl@0
   353
  mem_chunk->mem_area->free -= mem_chunk->atom_size;
sl@0
   354
  mem_chunk->mem_area->allocated += 1;
sl@0
   355
  
sl@0
   356
 outa_here:
sl@0
   357
  
sl@0
   358
  LEAVE_MEM_CHUNK_ROUTINE ();
sl@0
   359
  
sl@0
   360
  return mem;
sl@0
   361
}
sl@0
   362
sl@0
   363
gpointer
sl@0
   364
old_mem_chunk_alloc0 (GMemChunk *mem_chunk)
sl@0
   365
{
sl@0
   366
  gpointer mem;
sl@0
   367
  
sl@0
   368
  mem = old_mem_chunk_alloc (mem_chunk);
sl@0
   369
  if (mem)
sl@0
   370
    {
sl@0
   371
      memset (mem, 0, mem_chunk->atom_size);
sl@0
   372
    }
sl@0
   373
  
sl@0
   374
  return mem;
sl@0
   375
}
sl@0
   376
sl@0
   377
void
sl@0
   378
old_mem_chunk_free (GMemChunk *mem_chunk,
sl@0
   379
                    gpointer   mem)
sl@0
   380
{
sl@0
   381
  GMemArea *temp_area;
sl@0
   382
  GFreeAtom *free_atom;
sl@0
   383
  
sl@0
   384
  g_return_if_fail (mem_chunk != NULL);
sl@0
   385
  g_return_if_fail (mem != NULL);
sl@0
   386
  
sl@0
   387
  ENTER_MEM_CHUNK_ROUTINE ();
sl@0
   388
  
sl@0
   389
#ifdef ENABLE_GC_FRIENDLY
sl@0
   390
  memset (mem, 0, mem_chunk->atom_size);
sl@0
   391
#endif /* ENABLE_GC_FRIENDLY */
sl@0
   392
  
sl@0
   393
  /* Don't do anything if this is an ALLOC_ONLY chunk
sl@0
   394
   */
sl@0
   395
  if (mem_chunk->type == G_ALLOC_AND_FREE)
sl@0
   396
    {
sl@0
   397
      /* Place the memory on the "free_atoms" list
sl@0
   398
       */
sl@0
   399
      free_atom = (GFreeAtom*) mem;
sl@0
   400
      free_atom->next = mem_chunk->free_atoms;
sl@0
   401
      mem_chunk->free_atoms = free_atom;
sl@0
   402
      
sl@0
   403
      temp_area = g_tree_search (mem_chunk->mem_tree,
sl@0
   404
				 (GCompareFunc) old_mem_chunk_area_search,
sl@0
   405
				 mem);
sl@0
   406
      
sl@0
   407
      temp_area->allocated -= 1;
sl@0
   408
      
sl@0
   409
      if (temp_area->allocated == 0)
sl@0
   410
	{
sl@0
   411
	  temp_area->mark = 1;
sl@0
   412
	  mem_chunk->num_marked_areas += 1;
sl@0
   413
	}
sl@0
   414
    }
sl@0
   415
  
sl@0
   416
  LEAVE_MEM_CHUNK_ROUTINE ();
sl@0
   417
}
sl@0
   418
sl@0
   419
/* This doesn't free the free_area if there is one */
sl@0
   420
void
sl@0
   421
old_mem_chunk_clean (GMemChunk *mem_chunk)
sl@0
   422
{
sl@0
   423
  GMemArea *mem_area;
sl@0
   424
  GFreeAtom *prev_free_atom;
sl@0
   425
  GFreeAtom *temp_free_atom;
sl@0
   426
  gpointer mem;
sl@0
   427
  
sl@0
   428
  g_return_if_fail (mem_chunk != NULL);
sl@0
   429
  
sl@0
   430
  ENTER_MEM_CHUNK_ROUTINE ();
sl@0
   431
  
sl@0
   432
  if (mem_chunk->type == G_ALLOC_AND_FREE)
sl@0
   433
    {
sl@0
   434
      prev_free_atom = NULL;
sl@0
   435
      temp_free_atom = mem_chunk->free_atoms;
sl@0
   436
      
sl@0
   437
      while (temp_free_atom)
sl@0
   438
	{
sl@0
   439
	  mem = (gpointer) temp_free_atom;
sl@0
   440
	  
sl@0
   441
	  mem_area = g_tree_search (mem_chunk->mem_tree,
sl@0
   442
				    (GCompareFunc) old_mem_chunk_area_search,
sl@0
   443
				    mem);
sl@0
   444
	  
sl@0
   445
          /* If this mem area is marked for destruction then delete the
sl@0
   446
	   *  area and list node and decrement the free mem.
sl@0
   447
           */
sl@0
   448
	  if (mem_area->mark)
sl@0
   449
	    {
sl@0
   450
	      if (prev_free_atom)
sl@0
   451
		prev_free_atom->next = temp_free_atom->next;
sl@0
   452
	      else
sl@0
   453
		mem_chunk->free_atoms = temp_free_atom->next;
sl@0
   454
	      temp_free_atom = temp_free_atom->next;
sl@0
   455
	      
sl@0
   456
	      mem_area->free += mem_chunk->atom_size;
sl@0
   457
	      if (mem_area->free == mem_chunk->area_size)
sl@0
   458
		{
sl@0
   459
		  mem_chunk->num_mem_areas -= 1;
sl@0
   460
		  mem_chunk->num_marked_areas -= 1;
sl@0
   461
		  
sl@0
   462
		  if (mem_area->next)
sl@0
   463
		    mem_area->next->prev = mem_area->prev;
sl@0
   464
		  if (mem_area->prev)
sl@0
   465
		    mem_area->prev->next = mem_area->next;
sl@0
   466
		  if (mem_area == mem_chunk->mem_areas)
sl@0
   467
		    mem_chunk->mem_areas = mem_chunk->mem_areas->next;
sl@0
   468
		  if (mem_area == mem_chunk->mem_area)
sl@0
   469
		    mem_chunk->mem_area = NULL;
sl@0
   470
		  
sl@0
   471
		  if (mem_chunk->type == G_ALLOC_AND_FREE)
sl@0
   472
		    g_tree_remove (mem_chunk->mem_tree, mem_area);
sl@0
   473
		  g_free (mem_area);
sl@0
   474
		}
sl@0
   475
	    }
sl@0
   476
	  else
sl@0
   477
	    {
sl@0
   478
	      prev_free_atom = temp_free_atom;
sl@0
   479
	      temp_free_atom = temp_free_atom->next;
sl@0
   480
	    }
sl@0
   481
	}
sl@0
   482
    }
sl@0
   483
  LEAVE_MEM_CHUNK_ROUTINE ();
sl@0
   484
}
sl@0
   485
sl@0
   486
void
sl@0
   487
old_mem_chunk_reset (GMemChunk *mem_chunk)
sl@0
   488
{
sl@0
   489
  GMemArea *mem_areas;
sl@0
   490
  GMemArea *temp_area;
sl@0
   491
  
sl@0
   492
  g_return_if_fail (mem_chunk != NULL);
sl@0
   493
  
sl@0
   494
  ENTER_MEM_CHUNK_ROUTINE ();
sl@0
   495
  
sl@0
   496
  mem_areas = mem_chunk->mem_areas;
sl@0
   497
  mem_chunk->num_mem_areas = 0;
sl@0
   498
  mem_chunk->mem_areas = NULL;
sl@0
   499
  mem_chunk->mem_area = NULL;
sl@0
   500
  
sl@0
   501
  while (mem_areas)
sl@0
   502
    {
sl@0
   503
      temp_area = mem_areas;
sl@0
   504
      mem_areas = mem_areas->next;
sl@0
   505
      g_free (temp_area);
sl@0
   506
    }
sl@0
   507
  
sl@0
   508
  mem_chunk->free_atoms = NULL;
sl@0
   509
  
sl@0
   510
  if (mem_chunk->mem_tree)
sl@0
   511
    {
sl@0
   512
      g_tree_destroy (mem_chunk->mem_tree);
sl@0
   513
      mem_chunk->mem_tree = g_tree_new ((GCompareFunc) old_mem_chunk_area_compare);
sl@0
   514
    }
sl@0
   515
  
sl@0
   516
  LEAVE_MEM_CHUNK_ROUTINE ();
sl@0
   517
}
sl@0
   518
sl@0
   519
void
sl@0
   520
old_mem_chunk_print (GMemChunk *mem_chunk)
sl@0
   521
{
sl@0
   522
  GMemArea *mem_areas;
sl@0
   523
  gulong mem;
sl@0
   524
  
sl@0
   525
  g_return_if_fail (mem_chunk != NULL);
sl@0
   526
  
sl@0
   527
  mem_areas = mem_chunk->mem_areas;
sl@0
   528
  mem = 0;
sl@0
   529
  
sl@0
   530
  while (mem_areas)
sl@0
   531
    {
sl@0
   532
      mem += mem_chunk->area_size - mem_areas->free;
sl@0
   533
      mem_areas = mem_areas->next;
sl@0
   534
    }
sl@0
   535
  
sl@0
   536
  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO,
sl@0
   537
	 "%s: %ld bytes using %d mem areas",
sl@0
   538
	 mem_chunk->name, mem, mem_chunk->num_mem_areas);
sl@0
   539
}
sl@0
   540
sl@0
   541
void
sl@0
   542
old_mem_chunk_info (void)
sl@0
   543
{
sl@0
   544
  GMemChunk *mem_chunk;
sl@0
   545
  gint count;
sl@0
   546
  
sl@0
   547
  count = 0;
sl@0
   548
  g_mutex_lock (mem_chunks_lock);
sl@0
   549
  mem_chunk = mem_chunks;
sl@0
   550
  while (mem_chunk)
sl@0
   551
    {
sl@0
   552
      count += 1;
sl@0
   553
      mem_chunk = mem_chunk->next;
sl@0
   554
    }
sl@0
   555
  g_mutex_unlock (mem_chunks_lock);
sl@0
   556
  
sl@0
   557
  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "%d mem chunks", count);
sl@0
   558
  
sl@0
   559
  g_mutex_lock (mem_chunks_lock);
sl@0
   560
  mem_chunk = mem_chunks;
sl@0
   561
  g_mutex_unlock (mem_chunks_lock);
sl@0
   562
  
sl@0
   563
  while (mem_chunk)
sl@0
   564
    {
sl@0
   565
      old_mem_chunk_print ((GMemChunk*) mem_chunk);
sl@0
   566
      mem_chunk = mem_chunk->next;
sl@0
   567
    }  
sl@0
   568
}
sl@0
   569
sl@0
   570
static gulong
sl@0
   571
old_mem_chunk_compute_size (gulong size,
sl@0
   572
                            gulong min_size)
sl@0
   573
{
sl@0
   574
  gulong power_of_2;
sl@0
   575
  gulong lower, upper;
sl@0
   576
  
sl@0
   577
  power_of_2 = 16;
sl@0
   578
  while (power_of_2 < size)
sl@0
   579
    power_of_2 <<= 1;
sl@0
   580
  
sl@0
   581
  lower = power_of_2 >> 1;
sl@0
   582
  upper = power_of_2;
sl@0
   583
  
sl@0
   584
  if (size - lower < upper - size && lower >= min_size)
sl@0
   585
    return lower;
sl@0
   586
  else
sl@0
   587
    return upper;
sl@0
   588
}
sl@0
   589
sl@0
   590
static gint
sl@0
   591
old_mem_chunk_area_compare (GMemArea *a,
sl@0
   592
                            GMemArea *b)
sl@0
   593
{
sl@0
   594
  if (a->mem > b->mem)
sl@0
   595
    return 1;
sl@0
   596
  else if (a->mem < b->mem)
sl@0
   597
    return -1;
sl@0
   598
  return 0;
sl@0
   599
}
sl@0
   600
sl@0
   601
static gint
sl@0
   602
old_mem_chunk_area_search (GMemArea *a,
sl@0
   603
                           gchar    *addr)
sl@0
   604
{
sl@0
   605
  if (a->mem <= addr)
sl@0
   606
    {
sl@0
   607
      if (addr < &a->mem[a->index])
sl@0
   608
	return 0;
sl@0
   609
      return 1;
sl@0
   610
    }
sl@0
   611
  return -1;
sl@0
   612
}