Back to index

glibc  2.9
Classes | Defines | Typedefs | Functions | Variables
hurdmalloc.c File Reference
#include <stdlib.h>
#include <string.h>
#include "hurdmalloc.h"
#include <mach.h>
#include <assert.h>
#include <cthreads.h>

Go to the source code of this file.

Classes

struct  header
struct  free_list
union  header.u

Defines

#define vm_allocate   __vm_allocate
#define vm_page_size   __vm_page_size
#define MCHECK
#define CHECK_BUSY   0x8a3c743e
#define CHECK_FREE   0x66688b92
#define HEADER_SIZE   sizeof (struct header)
#define HEADER_NEXT(h)   ((h)->u.next)
#define HEADER_FREE(h)   ((h)->u.fl)
#define HEADER_CHECK(h)   ((h)->check)
#define MIN_SIZE   16
#define LOG2_MIN_SIZE   4
#define NBUCKETS   29

Typedefs

typedef struct headerheader_t
typedef struct free_listfree_list_t

Functions

static void malloc_init (void)
static void more_memory (int size, free_list_t fl)
void * malloc (size_t size)
void free (void *base)
void * realloc (void *old_base, size_t new_size)
static void malloc_fork_prepare (void)
static void malloc_fork_parent (void)
static void malloc_fork_child (void)
 text_set_element (_hurd_fork_prepare_hook, malloc_fork_prepare)
 text_set_element (_hurd_fork_parent_hook, malloc_fork_parent)
 text_set_element (_hurd_fork_child_hook, malloc_fork_child)
 text_set_element (_hurd_preinit_hook, malloc_init)

Variables

static struct free_list [NBUCKETS]

Class Documentation

struct header

Definition at line 98 of file hurdmalloc.c.

Class Members
long check
size_t length
size_t magic
const char *const * maybe
const char * name
size_t nmaybe
size_t nsyms
const char * subset
const char *const * syms
union header u
struct free_list

Definition at line 128 of file hurdmalloc.c.

Collaboration diagram for free_list:
Class Members
header_t head
spin_lock_t lock
union header.u

Definition at line 100 of file hurdmalloc.c.

Class Members
struct free_list * fl
struct header * next

Define Documentation

#define CHECK_BUSY   0x8a3c743e

Definition at line 93 of file hurdmalloc.c.

#define CHECK_FREE   0x66688b92

Definition at line 94 of file hurdmalloc.c.

#define HEADER_CHECK (   h)    ((h)->check)

Definition at line 109 of file hurdmalloc.c.

#define HEADER_FREE (   h)    ((h)->u.fl)

Definition at line 108 of file hurdmalloc.c.

#define HEADER_NEXT (   h)    ((h)->u.next)

Definition at line 107 of file hurdmalloc.c.

#define HEADER_SIZE   sizeof (struct header)

Definition at line 106 of file hurdmalloc.c.

#define LOG2_MIN_SIZE   4

Definition at line 111 of file hurdmalloc.c.

#define MCHECK

Definition at line 84 of file hurdmalloc.c.

#define MIN_SIZE   16

Definition at line 110 of file hurdmalloc.c.

#define NBUCKETS   29

Definition at line 142 of file hurdmalloc.c.

#define vm_allocate   __vm_allocate

Definition at line 7 of file hurdmalloc.c.

Definition at line 8 of file hurdmalloc.c.


Typedef Documentation

typedef struct free_list * free_list_t
typedef struct header * header_t

Function Documentation

void free ( void *  base)

Definition at line 272 of file hurdmalloc.c.

{
       register header_t h;
       register free_list_t fl;
       register int i;

       if (base == 0)
              return;
       /*
        * Find free list for block.
        */
       h = (header_t) (base - HEADER_SIZE);

#ifdef MCHECK
       assert (HEADER_CHECK (h) == CHECK_BUSY);
#endif

       fl = HEADER_FREE (h);
       i = fl - malloc_free_list;
       /*
        * Sanity checks.
        */
       if (i < 0 || i >= NBUCKETS) {
              ASSERT(0 <= i && i < NBUCKETS);
              return;
       }
       if (fl != &malloc_free_list[i]) {
              ASSERT(fl == &malloc_free_list[i]);
              return;
       }
       /*
        * Push block on free list.
        */
       spin_lock(&fl->lock);
       HEADER_NEXT (h) = fl->head;
#ifdef MCHECK
       HEADER_CHECK (h) = CHECK_FREE;
#endif
       fl->head = h;
#ifdef DEBUG
       fl->in_use -= 1;
#endif /* DEBUG */
       spin_unlock(&fl->lock);
       return;
}
void* malloc ( size_t  size)

Definition at line 205 of file hurdmalloc.c.

{
       register int i, n;
       register free_list_t fl;
       register header_t h;

       if ((int) size < 0)         /* sanity check */
              return 0;
       size += HEADER_SIZE;
       /*
        * Find smallest power-of-two block size
        * big enough to hold requested size plus header.
        */
       i = 0;
       n = MIN_SIZE;
       while (n < size) {
              i += 1;
              n <<= 1;
       }
       ASSERT(i < NBUCKETS);
       fl = &malloc_free_list[i];
       spin_lock(&fl->lock);
       h = fl->head;
       if (h == 0) {
              /*
               * Free list is empty;
               * allocate more blocks.
               */
              more_memory(n, fl);
              h = fl->head;
              if (h == 0) {
                     /*
                      * Allocation failed.
                      */
                     spin_unlock(&fl->lock);
                     return 0;
              }
       }
       /*
        * Pop block from free list.
        */
       fl->head = HEADER_NEXT (h);

#ifdef MCHECK
       assert (HEADER_CHECK (h) == CHECK_FREE);
       HEADER_CHECK (h) = CHECK_BUSY;
#endif

#ifdef DEBUG
       fl->in_use += 1;
#endif /* DEBUG */
       spin_unlock(&fl->lock);
       /*
        * Store free list pointer in block header
        * so we can figure out where it goes
        * at free() time.
        */
       HEADER_FREE (h) = fl;
       /*
        * Return pointer past the block header.
        */
       return ((char *) h) + HEADER_SIZE;
}

Here is the call graph for this function:

static void malloc_fork_child ( void  ) [static]

Definition at line 440 of file hurdmalloc.c.

{
    register int i;

    for (i = NBUCKETS-1; i >= 0; i--) {
       spin_unlock(&malloc_free_list[i].lock);
    }
}
static void malloc_fork_parent ( void  ) [static]

Definition at line 427 of file hurdmalloc.c.

{
    register int i;

    for (i = NBUCKETS-1; i >= 0; i--) {
       spin_unlock(&malloc_free_list[i].lock);
    }
}
static void malloc_fork_prepare ( void  ) [static]

Definition at line 413 of file hurdmalloc.c.

{
    register int i;

    for (i = 0; i < NBUCKETS; i++) {
       spin_lock(&malloc_free_list[i].lock);
    }
}
static void malloc_init ( void  ) [static]

Definition at line 153 of file hurdmalloc.c.

{
  int i;
  for (i = 0; i < NBUCKETS; ++i)
    {
      spin_lock_init (&malloc_free_list[i].lock);
      malloc_free_list[i].head = NULL;
#ifdef DEBUG
      malloc_free_list[i].in_use = 0;
#endif
    }

  /* This not only suppresses a `defined but not used' warning,
     but it is ABSOLUTELY NECESSARY to avoid the hyperclever
     compiler from "optimizing out" the entire function!  */
  (void) &malloc_init;
}
static void more_memory ( int  size,
free_list_t  fl 
) [static]

Definition at line 172 of file hurdmalloc.c.

{
       register int amount;
       register int n;
       vm_address_t where;
       register header_t h;
       kern_return_t r;

       if (size <= vm_page_size) {
              amount = vm_page_size;
              n = vm_page_size / size;
              /* We lose vm_page_size - n*size bytes here.  */
       } else {
              amount = size;
              n = 1;
       }

       r = vm_allocate(mach_task_self(), &where, (vm_size_t) amount, TRUE);
       assert_perror (r);

       h = (header_t) where;
       do {
              HEADER_NEXT (h) = fl->head;
#ifdef MCHECK
              HEADER_CHECK (h) = CHECK_FREE;
#endif
              fl->head = h;
              h = (header_t) ((char *) h + size);
       } while (--n != 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* realloc ( void *  old_base,
size_t  new_size 
)

Definition at line 321 of file hurdmalloc.c.

{
       register header_t h;
       register free_list_t fl;
       register int i;
       unsigned int old_size;
       char *new_base;

       if (old_base == 0)
         return malloc (new_size);

       /*
        * Find size of old block.
        */
       h = (header_t) (old_base - HEADER_SIZE);
#ifdef MCHECK
       assert (HEADER_CHECK (h) == CHECK_BUSY);
#endif
       fl = HEADER_FREE (h);
       i = fl - malloc_free_list;
       /*
        * Sanity checks.
        */
       if (i < 0 || i >= NBUCKETS) {
              ASSERT(0 <= i && i < NBUCKETS);
              return 0;
       }
       if (fl != &malloc_free_list[i]) {
              ASSERT(fl == &malloc_free_list[i]);
              return 0;
       }
       /*
        * Free list with index i contains blocks of size
        * 2 ^ (i + * LOG2_MIN_SIZE) including header.
        */
       old_size = (1 << (i + LOG2_MIN_SIZE)) - HEADER_SIZE;

       if (new_size <= old_size
           && new_size > (((old_size + HEADER_SIZE) >> 1) - HEADER_SIZE))
         /* The new size still fits in the same block, and wouldn't fit in
            the next smaller block!  */
         return old_base;

       /*
        * Allocate new block, copy old bytes, and free old block.
        */
       new_base = malloc(new_size);
       if (new_base)
         memcpy (new_base, old_base,
                (int) (old_size < new_size ? old_size : new_size));

       if (new_base || new_size == 0)
         /* Free OLD_BASE, but only if the malloc didn't fail.  */
         free (old_base);

       return new_base;
}
text_set_element ( _hurd_fork_prepare_hook  ,
malloc_fork_prepare   
)
text_set_element ( _hurd_fork_parent_hook  ,
malloc_fork_parent   
)
text_set_element ( _hurd_fork_child_hook  ,
malloc_fork_child   
)
text_set_element ( _hurd_preinit_hook  ,
malloc_init   
)

Variable Documentation

struct free_list[NBUCKETS] [static]

Definition at line 144 of file hurdmalloc.c.