Back to index

glibc  2.9
Classes | Defines | Typedefs | Functions | Variables
arena.c File Reference
#include <stdbool.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _heap_info

Defines

#define HEAP_MIN_SIZE   (32*1024)
#define HEAP_MAX_SIZE   (1024*1024) /* must be a power of two */
#define THREAD_STATS   0
#define top(ar_ptr)   ((ar_ptr)->top)
#define THREAD_STAT(x)   do ; while(0)
#define arena_get(ar_ptr, sz)
#define arena_for_chunk(ptr)   (&main_arena)
#define ATFORK_ARENA_PTR   ((Void_t*)-1)
#define ptmalloc_unlock_all2   ptmalloc_unlock_all

Typedefs

typedef struct _heap_info heap_info

Functions

static Void_tmalloc_atfork (size_t sz, const Void_t *caller)
static void free_atfork (Void_t *mem, const Void_t *caller)
static void ptmalloc_lock_all (void)
static void ptmalloc_unlock_all (void)
static void ptmalloc_init_minimal (void)
static void ptmalloc_init (void)

Variables

int sanity_check_heap_info_alignment [(sizeof(heap_info)+2 *SIZE_SZ)%MALLOC_ALIGNMENT?-1:1]
static tsd_key_t arena_key
static mutex_t list_lock
static unsigned long arena_mem
int __malloc_initialized = -1
static __malloc_ptr_t(* save_malloc_hook )(size_t __size, __const __malloc_ptr_t)
static __malloc_ptr_t(* save_memalign_hook )(size_t __align, size_t __size, __const __malloc_ptr_t)
static void(* save_free_hook )(__malloc_ptr_t __ptr, __const __malloc_ptr_t)
static Void_tsave_arena
static unsigned int atfork_recursive_cntr

Class Documentation

struct _heap_info

Definition at line 59 of file arena.c.

Collaboration diagram for _heap_info:
Class Members
mstate ar_ptr
size_t mprotect_size
char pad
struct _heap_info * prev
size_t size

Define Documentation

#define arena_for_chunk (   ptr)    (&main_arena)

Definition at line 143 of file arena.c.

#define arena_get (   ar_ptr,
  sz 
)
Value:
do { \
  ar_ptr = &main_arena; \
  (void)mutex_lock(&ar_ptr->mutex); \
} while(0)

Definition at line 138 of file arena.c.

#define ATFORK_ARENA_PTR   ((Void_t*)-1)

Definition at line 170 of file arena.c.

#define HEAP_MAX_SIZE   (1024*1024) /* must be a power of two */

Definition at line 31 of file arena.c.

#define HEAP_MIN_SIZE   (32*1024)

Definition at line 26 of file arena.c.

Definition at line 326 of file arena.c.

#define THREAD_STAT (   x)    do ; while(0)

Definition at line 86 of file arena.c.

#define THREAD_STATS   0

Definition at line 44 of file arena.c.

#define top (   ar_ptr)    ((ar_ptr)->top)

Definition at line 52 of file arena.c.


Typedef Documentation

typedef struct _heap_info heap_info

Function Documentation

static void free_atfork ( Void_t mem,
const Void_t caller 
) [static]

Definition at line 203 of file arena.c.

{
  Void_t *vptr = NULL;
  mstate ar_ptr;
  mchunkptr p;                          /* chunk corresponding to mem */

  if (mem == 0)                              /* free(0) has no effect */
    return;

  p = mem2chunk(mem);         /* do not bother to replicate free_check here */

#if HAVE_MMAP
  if (chunk_is_mmapped(p))                       /* release mmapped memory. */
  {
    munmap_chunk(p);
    return;
  }
#endif

  ar_ptr = arena_for_chunk(p);
  tsd_getspecific(arena_key, vptr);
  if(vptr != ATFORK_ARENA_PTR)
    (void)mutex_lock(&ar_ptr->mutex);
  _int_free(ar_ptr, mem);
  if(vptr != ATFORK_ARENA_PTR)
    (void)mutex_unlock(&ar_ptr->mutex);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Void_t* malloc_atfork ( size_t  sz,
const Void_t caller 
) [static]

Definition at line 176 of file arena.c.

{
  Void_t *vptr = NULL;
  Void_t *victim;

  tsd_getspecific(arena_key, vptr);
  if(vptr == ATFORK_ARENA_PTR) {
    /* We are the only thread that may allocate at all.  */
    if(save_malloc_hook != malloc_check) {
      return _int_malloc(&main_arena, sz);
    } else {
      if(top_check()<0)
        return 0;
      victim = _int_malloc(&main_arena, sz+1);
      return mem2mem_check(victim, sz);
    }
  } else {
    /* Suspend the thread until the `atfork' handlers have completed.
       By that time, the hooks will have been reset as well, so that
       mALLOc() can be used again. */
    (void)mutex_lock(&list_lock);
    (void)mutex_unlock(&list_lock);
    return public_mALLOc(sz);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ptmalloc_init ( void  ) [static]

Definition at line 425 of file arena.c.

{
#if __STD_C
  const char* s;
#else
  char* s;
#endif
  int secure = 0;

  if(__malloc_initialized >= 0) return;
  __malloc_initialized = 0;

#ifdef _LIBC
# if defined SHARED && !USE___THREAD
  /* ptmalloc_init_minimal may already have been called via
     __libc_malloc_pthread_startup, above.  */
  if (mp_.pagesize == 0)
# endif
#endif
    ptmalloc_init_minimal();

#ifndef NO_THREADS
# if defined _LIBC
  /* We know __pthread_initialize_minimal has already been called,
     and that is enough.  */
#   define NO_STARTER
# endif
# ifndef NO_STARTER
  /* With some threads implementations, creating thread-specific data
     or initializing a mutex may call malloc() itself.  Provide a
     simple starter version (realloc() won't work). */
  save_malloc_hook = __malloc_hook;
  save_memalign_hook = __memalign_hook;
  save_free_hook = __free_hook;
  __malloc_hook = malloc_starter;
  __memalign_hook = memalign_starter;
  __free_hook = free_starter;
#  ifdef _LIBC
  /* Initialize the pthreads interface. */
  if (__pthread_initialize != NULL)
    __pthread_initialize();
#  endif /* !defined _LIBC */
# endif       /* !defined NO_STARTER */
#endif /* !defined NO_THREADS */
  mutex_init(&main_arena.mutex);
  main_arena.next = &main_arena;

#if defined _LIBC && defined SHARED
  /* In case this libc copy is in a non-default namespace, never use brk.
     Likewise if dlopened from statically linked program.  */
  Dl_info di;
  struct link_map *l;

  if (_dl_open_hook != NULL
      || (_dl_addr (ptmalloc_init, &di, &l, NULL) != 0
         && l->l_ns != LM_ID_BASE))
    __morecore = __failing_morecore;
#endif

  mutex_init(&list_lock);
  tsd_key_create(&arena_key, NULL);
  tsd_setspecific(arena_key, (Void_t *)&main_arena);
  thread_atfork(ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2);
#ifndef NO_THREADS
# ifndef NO_STARTER
  __malloc_hook = save_malloc_hook;
  __memalign_hook = save_memalign_hook;
  __free_hook = save_free_hook;
# else
#  undef NO_STARTER
# endif
#endif
#ifdef _LIBC
  secure = __libc_enable_secure;
  s = NULL;
  if (__builtin_expect (_environ != NULL, 1))
    {
      char **runp = _environ;
      char *envline;

      while (__builtin_expect ((envline = next_env_entry (&runp)) != NULL,
                            0))
       {
         size_t len = strcspn (envline, "=");

         if (envline[len] != '=')
           /* This is a "MALLOC_" variable at the end of the string
              without a '=' character.  Ignore it since otherwise we
              will access invalid memory below.  */
           continue;

         switch (len)
           {
           case 6:
             if (memcmp (envline, "CHECK_", 6) == 0)
              s = &envline[7];
             break;
           case 8:
             if (! secure)
              {
                if (memcmp (envline, "TOP_PAD_", 8) == 0)
                  mALLOPt(M_TOP_PAD, atoi(&envline[9]));
                else if (memcmp (envline, "PERTURB_", 8) == 0)
                  mALLOPt(M_PERTURB, atoi(&envline[9]));
              }
             break;
           case 9:
             if (! secure && memcmp (envline, "MMAP_MAX_", 9) == 0)
              mALLOPt(M_MMAP_MAX, atoi(&envline[10]));
             break;
           case 15:
             if (! secure)
              {
                if (memcmp (envline, "TRIM_THRESHOLD_", 15) == 0)
                  mALLOPt(M_TRIM_THRESHOLD, atoi(&envline[16]));
                else if (memcmp (envline, "MMAP_THRESHOLD_", 15) == 0)
                  mALLOPt(M_MMAP_THRESHOLD, atoi(&envline[16]));
              }
             break;
           default:
             break;
           }
       }
    }
#else
  if (! secure)
    {
      if((s = getenv("MALLOC_TRIM_THRESHOLD_")))
       mALLOPt(M_TRIM_THRESHOLD, atoi(s));
      if((s = getenv("MALLOC_TOP_PAD_")))
       mALLOPt(M_TOP_PAD, atoi(s));
      if((s = getenv("MALLOC_PERTURB_")))
       mALLOPt(M_PERTURB, atoi(s));
      if((s = getenv("MALLOC_MMAP_THRESHOLD_")))
       mALLOPt(M_MMAP_THRESHOLD, atoi(s));
      if((s = getenv("MALLOC_MMAP_MAX_")))
       mALLOPt(M_MMAP_MAX, atoi(s));
    }
  s = getenv("MALLOC_CHECK_");
#endif
  if(s && s[0]) {
    mALLOPt(M_CHECK_ACTION, (int)(s[0] - '0'));
    if (check_action != 0)
      __malloc_check_init();
  }
  if(__malloc_initialize_hook != NULL)
    (*__malloc_initialize_hook)();
  __malloc_initialized = 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ptmalloc_init_minimal ( void  ) [static]

Definition at line 371 of file arena.c.

{
#if DEFAULT_TOP_PAD != 0
  mp_.top_pad        = DEFAULT_TOP_PAD;
#endif
  mp_.n_mmaps_max    = DEFAULT_MMAP_MAX;
  mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
  mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD;
  mp_.pagesize       = malloc_getpagesize;
}

Here is the caller graph for this function:

static void ptmalloc_lock_all ( void  ) [static]

Definition at line 242 of file arena.c.

{
  mstate ar_ptr;

  if(__malloc_initialized < 1)
    return;
  if (mutex_trylock(&list_lock))
    {
      Void_t *my_arena;
      tsd_getspecific(arena_key, my_arena);
      if (my_arena == ATFORK_ARENA_PTR)
       /* This is the same thread which already locks the global list.
          Just bump the counter.  */
       goto out;

      /* This thread has to wait its turn.  */
      (void)mutex_lock(&list_lock);
    }
  for(ar_ptr = &main_arena;;) {
    (void)mutex_lock(&ar_ptr->mutex);
    ar_ptr = ar_ptr->next;
    if(ar_ptr == &main_arena) break;
  }
  save_malloc_hook = __malloc_hook;
  save_free_hook = __free_hook;
  __malloc_hook = malloc_atfork;
  __free_hook = free_atfork;
  /* Only the current thread may perform malloc/free calls now. */
  tsd_getspecific(arena_key, save_arena);
  tsd_setspecific(arena_key, ATFORK_ARENA_PTR);
 out:
  ++atfork_recursive_cntr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ptmalloc_unlock_all ( void  ) [static]

Definition at line 277 of file arena.c.

{
  mstate ar_ptr;

  if(__malloc_initialized < 1)
    return;
  if (--atfork_recursive_cntr != 0)
    return;
  tsd_setspecific(arena_key, save_arena);
  __malloc_hook = save_malloc_hook;
  __free_hook = save_free_hook;
  for(ar_ptr = &main_arena;;) {
    (void)mutex_unlock(&ar_ptr->mutex);
    ar_ptr = ar_ptr->next;
    if(ar_ptr == &main_arena) break;
  }
  (void)mutex_unlock(&list_lock);
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 93 of file arena.c.

tsd_key_t arena_key [static]

Definition at line 79 of file arena.c.

unsigned long arena_mem [static]

Definition at line 90 of file arena.c.

unsigned int atfork_recursive_cntr [static]

Definition at line 233 of file arena.c.

mutex_t list_lock [static]

Definition at line 80 of file arena.c.

Void_t* save_arena [static]

Definition at line 161 of file arena.c.

Definition at line 159 of file arena.c.

Definition at line 153 of file arena.c.

Definition at line 156 of file arena.c.