Alien-Judy

 view release on metacpan or  search on metacpan

src/judy-1.0.5/test/malloc-pre2.8a.c  view on Meta::CPAN


/*
  M_MXFAST is the maximum request size used for "fastbins", special bins
  that hold returned chunks without consolidating their spaces. This
  enables future requests for chunks of the same size to be handled
  very quickly, but can increase fragmentation, and thus increase the
  overall memory footprint of a program.

  This malloc manages fastbins very conservatively yet still
  efficiently, so fragmentation is rarely a problem for values less
  than or equal to the default.  The maximum supported value of MXFAST
  is 64 (also the default). You wouldn't want it any higher than this
  anyway.  Fastbins are designed especially for use with many small
  structs, objects or strings -- the default handles
  structs/objects/arrays with sizes up to 16 4byte fields, or small
  strings representing words, tokens, etc. Using fastbins for larger
  objects normally worsens fragmentation without improving speed.

  M_MXFAST is set in REQUEST size units. It is internally used in
  chunksize units, which adds padding and alignment.  You can reduce
  M_MXFAST to 0 to disable all use of fastbins.  This causes the malloc
  algorithm to be a closer approximation of fifo-best-fit in all cases,
  not just for larger requests, but will generally cause it to be
  slower.
*/


/* M_MXFAST is a standard SVID/XPG tuning option, usually listed in malloc.h */
#ifndef M_MXFAST
#define M_MXFAST            1    
#endif

#ifndef DEFAULT_MXFAST
#define DEFAULT_MXFAST     64
#endif


/*
  M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
  to keep before releasing via malloc_trim in free().

  Automatic trimming is mainly useful in long-lived programs.
  Because trimming via sbrk can be slow on some systems, and can
  sometimes be wasteful (in cases where programs immediately
  afterward allocate more large chunks) the value should be high
  enough so that your overall system performance would improve by
  releasing this much memory.

  The trim threshold and the mmap control parameters (see below)
  can be traded off with one another. Trimming and mmapping are
  two different ways of releasing unused memory back to the
  system. Between these two, it is often possible to keep
  system-level demands of a long-lived program down to a bare
  minimum. For example, in one test suite of sessions measuring
  the XF86 X server on Linux, using a trim threshold of 128K and a
  mmap threshold of 192K led to near-minimal long term resource
  consumption.

  If you are using this malloc in a long-lived program, it should
  pay to experiment with these values.  As a rough guide, you
  might set to a value close to the average size of a process
  (program) running on your system.  Releasing this much memory
  would allow such a process to run in memory.  Generally, it's
  worth it to tune for trimming rather tham memory mapping when a
  program undergoes phases where several large chunks are
  allocated and released in ways that can reuse each other's
  storage, perhaps mixed with phases where there are no such
  chunks at all.  And in well-behaved long-lived programs,
  controlling release of large blocks via trimming versus mapping
  is usually faster.

  However, in most programs, these parameters serve mainly as
  protection against the system-level effects of carrying around
  massive amounts of unneeded memory. Since frequent calls to
  sbrk, mmap, and munmap otherwise degrade performance, the default
  parameters are set to relatively high values that serve only as
  safeguards.

  The trim value must be greater than page size to have any useful
  effect.  To disable trimming completely, you can set to 
  (unsigned long)(-1)

  Trim settings interact with fastbin (MXFAST) settings: Unless
  TRIM_FASTBINS is defined, automatic trimming never takes place upon
  freeing a chunk with size less than or equal to MXFAST. Trimming is
  instead delayed until subsequent freeing of larger chunks. However,
  you can still force an attempted trim by calling malloc_trim.

  Also, trimming is not generally possible in cases where
  the main arena is obtained via mmap.

  Note that the trick some people use of mallocing a huge space and
  then freeing it at program startup, in an attempt to reserve system
  memory, doesn't have the intended effect under automatic trimming,
  since that memory will immediately be returned to the system.
*/

#define M_TRIM_THRESHOLD       -1

#ifndef DEFAULT_TRIM_THRESHOLD

#define DEFAULT_TRIM_THRESHOLD (-1U)
/* #define DEFAULT_TRIM_THRESHOLD (256 * 1024) */
#endif

/*
  M_TOP_PAD is the amount of extra `padding' space to allocate or
  retain whenever sbrk is called. It is used in two ways internally:

  * When sbrk is called to extend the top of the arena to satisfy
  a new malloc request, this much padding is added to the sbrk
  request.

  * When malloc_trim is called automatically from free(),
  it is used as the `pad' argument.

  In both cases, the actual amount of padding is rounded
  so that the end of the arena is always a system page boundary.

  The main reason for using padding is to avoid calling sbrk so
  often. Having even a small pad greatly reduces the likelihood
  that nearly every malloc request during program start-up (or
  after trimming) will invoke sbrk, which needlessly wastes

src/judy-1.0.5/test/malloc-pre2.8a.c  view on Meta::CPAN

    n += m; 
    x = (x << m) >> 14;
    m = 13 - n + (x & ~(x>>1));
    /* shift up n and use the next bit to make finer-granularity bins. */
    return (m << 1) + ((sz >> (m + (TREE_BIN_SHIFT-1)) & 1));
  }
#endif
}

static bin_index_t bit2idx(bitmap_t x) {
#if defined(__GNUC__) && defined(i386)
  int r;
  __asm__("bsfl %1,%0\n\t"
	 : "=r" (r) : "g" (x));
  return (bin_index_t)r;
#else
  return (bin_index_t)(ffs(x)-1);
#endif
}



#define bin_index(sz) \
 ((in_smallbin_range(sz)) ? smallbin_index(sz) : treebin_index(sz))

/*
  The most significant bit distinguishing nodes in the tree
  associated with a given bin
*/

#define CHUNK_SIZE_BITS (sizeof(CHUNK_SIZE_T) * 8)

#define bitshift_for_index(idx) \
  (idx == NBINS-1)? \
    CHUNK_SIZE_BITS-1 : \
    (((idx) >> 1) + TREE_BIN_SHIFT-2)

#define tbin_at(m,i) (&((m)->treebins[i]))

#define minsize_for_treeindex(i)                             \
    (((CHUNK_SIZE_T)(1) << (((i) >> 1) + TREE_BIN_SHIFT)) |  \
    (((CHUNK_SIZE_T)((i) & 1)) <<                            \
     ( ( (i) >> 1) + TREE_BIN_SHIFT - 1)))



#define is_tbin(M, P) ((tbinptr*)(P) >= &((M)->treebins[0]) && \
                       (tbinptr*)(P) <  &((M)->treebins[NBINS]))

#define leftmost_child(t) \
  (((t)->child[0] != 0)? ((t)->child[0]) : ((t)->child[1]))


/*
  Fastbins

    An array of lists holding recently freed small chunks.  Fastbins
    are not doubly linked.  It is faster to single-link them, and
    since chunks are never removed from the middles of these lists,
    double linking is not necessary. Also, unlike regular bins, they
    are not even processed in FIFO order (they use faster LIFO) since
    ordering doesn't much matter in the transient contexts in which
    fastbins are normally used.

    Chunks in fastbins keep their inuse bit set, so they cannot
    be consolidated with other free chunks. malloc_consolidate
    releases all chunks in fastbins and consolidates them with
    other free chunks. 
*/

typedef struct malloc_chunk* mfastbinptr;

#define fastbin_at(m,i) (&((m)->fastbins[i]))

/* offset 2 to use otherwise unindexable first 2 bins */
#define fastbin_index(sz)        ((((unsigned int)(sz)) >> 3) - 2)


/* The maximum fastbin request size we support */
#define MAX_FAST_REQUEST     64

#define MAX_FAST_SIZE (request2size(MAX_FAST_REQUEST))

#define NFASTBINS  (fastbin_index(MAX_FAST_SIZE)+1)

/*
  FASTCHUNKS_BIT held in max_fast indicates that there are probably
  some fastbin chunks. It is set true on entering a chunk into any
  fastbin, and cleared only in malloc_consolidate.
*/

#define FASTCHUNKS_BIT        (2U)

#define have_fastchunks(M)   (((M)->max_fast &  FASTCHUNKS_BIT))
#define set_fastchunks(M)    ((M)->max_fast |=  (FASTCHUNKS_BIT))
#define clear_fastchunks(M)  ((M)->max_fast &= ~(FASTCHUNKS_BIT))

/* 
   Set value of max_fast. 
   Use impossibly small value if 0.
*/

#define set_max_fast(M, s) \
  (M)->max_fast = (((s) == 0)? SMALLBIN_WIDTH: request2size(s)) | \
  ((M)->max_fast &  (FASTCHUNKS_BIT))

#define get_max_fast(M) \
  ((M)->max_fast & ~(FASTCHUNKS_BIT))


/*
  Top

    The top-most available chunk (i.e., the one bordering the end of
    available memory) is treated specially. It is never included in
    any bin, is used only if no other chunk is available, and is
    released back to the system if it is very large (see
    M_TRIM_THRESHOLD).   

    Top initially points to a dummy bin with zero size, thus forcing
    extension on the first malloc request, so we avoid having any



( run in 1.275 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )