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

📄 dlmalloc-2.6.6.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
// On Win32 platforms, 'memset()' and 'memcpy()' are already declared in
// 'windows.h'
#else
Void_t* memset();
Void_t* memcpy();
#endif
#endif
#endif

#if USE_MEMCPY

/* The following macros are only invoked with (2n+1)-multiples of
   INTERNAL_SIZE_T units, with a positive integer n. This is exploited
   for fast inline execution when n is small. */

#define MALLOC_ZERO(charp, nbytes)                                            \do {                                                                          \  INTERNAL_SIZE_T mzsz = (nbytes);                                            \  if(mzsz <= 9*sizeof(mzsz)) {                                                \    INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp);                         \    if(mzsz >= 5*sizeof(mzsz)) {     *mz++ = 0;                               \                                     *mz++ = 0;                               \      if(mzsz >= 7*sizeof(mzsz)) {   *mz++ = 0;                               \                                     *mz++ = 0;                               \        if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0;                               \                                     *mz++ = 0; }}}                           \                                     *mz++ = 0;                               \                                     *mz++ = 0;                               \                                     *mz   = 0;                               \  } else memset((charp), 0, mzsz);                                            \} while(0)

#define MALLOC_COPY(dest,src,nbytes)                                          \do {                                                                          \  INTERNAL_SIZE_T mcsz = (nbytes);                                            \  if(mcsz <= 9*sizeof(mcsz)) {                                                \    INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src);                        \    INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest);                       \    if(mcsz >= 5*sizeof(mcsz)) {     *mcdst++ = *mcsrc++;                     \                                     *mcdst++ = *mcsrc++;                     \      if(mcsz >= 7*sizeof(mcsz)) {   *mcdst++ = *mcsrc++;                     \                                     *mcdst++ = *mcsrc++;                     \        if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++;                     \                                     *mcdst++ = *mcsrc++; }}}                 \                                     *mcdst++ = *mcsrc++;                     \                                     *mcdst++ = *mcsrc++;                     \                                     *mcdst   = *mcsrc  ;                     \  } else memcpy(dest, src, mcsz);                                             \} while(0)

#else /* !USE_MEMCPY */

/* Use Duff's device for good zeroing/copying performance. */

#define MALLOC_ZERO(charp, nbytes)                                            \do {                                                                          \  INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp);                           \  long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \  if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \  switch (mctmp) {                                                            \    case 0: for(;;) { *mzp++ = 0;                                             \    case 7:           *mzp++ = 0;                                             \    case 6:           *mzp++ = 0;                                             \    case 5:           *mzp++ = 0;                                             \    case 4:           *mzp++ = 0;                                             \    case 3:           *mzp++ = 0;                                             \    case 2:           *mzp++ = 0;                                             \    case 1:           *mzp++ = 0; if(mcn <= 0) break; mcn--; }                \  }                                                                           \} while(0)

#define MALLOC_COPY(dest,src,nbytes)                                          \do {                                                                          \  INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src;                            \  INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest;                           \  long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \  if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \  switch (mctmp) {                                                            \    case 0: for(;;) { *mcdst++ = *mcsrc++;                                    \    case 7:           *mcdst++ = *mcsrc++;                                    \    case 6:           *mcdst++ = *mcsrc++;                                    \    case 5:           *mcdst++ = *mcsrc++;                                    \    case 4:           *mcdst++ = *mcsrc++;                                    \    case 3:           *mcdst++ = *mcsrc++;                                    \    case 2:           *mcdst++ = *mcsrc++;                                    \    case 1:           *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; }       \  }                                                                           \} while(0)

#endif


/*
  Define HAVE_MMAP to optionally make malloc() use mmap() to
  allocate very large blocks.  These will be returned to the
  operating system immediately after a free().
*/

#ifndef HAVE_MMAP
#define HAVE_MMAP 1
#endif

/*
  Define HAVE_MREMAP to make realloc() use mremap() to re-allocate
  large blocks.  This is currently only possible on Linux with
  kernel versions newer than 1.3.77.
*/

#ifndef HAVE_MREMAP
#ifdef INTERNAL_LINUX_C_LIB
#define HAVE_MREMAP 1
#else
#define HAVE_MREMAP 0
#endif
#endif

#if HAVE_MMAP

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
#endif

#endif /* HAVE_MMAP */

/*
  Access to system page size. To the extent possible, this malloc
  manages memory from the system in page-size units.
  
  The following mechanics for getpagesize were adapted from 
  bsd/gnu getpagesize.h 
*/

#ifndef LACKS_UNISTD_H
#  include <unistd.h>
#endif

#ifndef malloc_getpagesize
#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
#    ifndef _SC_PAGE_SIZE
#      define _SC_PAGE_SIZE _SC_PAGESIZE
#    endif
#  endif
#  ifdef _SC_PAGE_SIZE
#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
#  else
#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
       extern size_t getpagesize();
#      define malloc_getpagesize getpagesize()
#    else
#      ifdef WIN32
#        define malloc_getpagesize (4096) /* TBD: Use 'GetSystemInfo' instead */
#      else
#        ifndef LACKS_SYS_PARAM_H
#          include <sys/param.h>
#        endif
#        ifdef EXEC_PAGESIZE
#          define malloc_getpagesize EXEC_PAGESIZE
#        else
#          ifdef NBPG
#            ifndef CLSIZE
#              define malloc_getpagesize NBPG
#            else
#              define malloc_getpagesize (NBPG * CLSIZE)
#            endif
#          else 
#            ifdef NBPC
#              define malloc_getpagesize NBPC
#            else
#              ifdef PAGESIZE
#                define malloc_getpagesize PAGESIZE
#              else
#                define malloc_getpagesize (4096) /* just guess */
#              endif
#            endif
#          endif 
#        endif
#      endif 
#    endif
#  endif
#endif



/*

  This version of malloc supports the standard SVID/XPG mallinfo
  routine that returns a struct containing the same kind of
  information you can get from malloc_stats. It should work on
  any SVID/XPG compliant system that has a /usr/include/malloc.h
  defining struct mallinfo. (If you'd like to install such a thing
  yourself, cut out the preliminary declarations as described above
  and below and save them in a malloc.h file. But there's no
  compelling reason to bother to do this.)

  The main declaration needed is the mallinfo struct that is returned
  (by-copy) by mallinfo().  The SVID/XPG malloinfo struct contains a
  bunch of fields, most of which are not even meaningful in this
  version of malloc. Some of these fields are are instead filled by
  mallinfo() with other numbers that might possibly be of interest.

  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
  /usr/include/malloc.h file that includes a declaration of struct
  mallinfo.  If so, it is included; else an SVID2/XPG2 compliant
  version is declared below.  These must be precisely the same for
  mallinfo() to work.

*/

/* #define HAVE_USR_INCLUDE_MALLOC_H */

#if HAVE_USR_INCLUDE_MALLOC_H
#include "/usr/include/malloc.h"
#else

/* SVID2/XPG mallinfo structure */

struct mallinfo {
  int arena;    /* total space allocated from system */
  int ordblks;  /* number of non-inuse chunks */
  int smblks;   /* unused -- always zero */
  int hblks;    /* number of mmapped regions */
  int hblkhd;   /* total space in mmapped regions */
  int usmblks;  /* unused -- always zero */
  int fsmblks;  /* unused -- always zero */
  int uordblks; /* total allocated space */
  int fordblks; /* total non-inuse space */
  int keepcost; /* top-most, releasable (via malloc_trim) space */
};	

/* SVID2/XPG mallopt options */

#define M_MXFAST  1    /* UNUSED in this malloc */
#define M_NLBLKS  2    /* UNUSED in this malloc */
#define M_GRAIN   3    /* UNUSED in this malloc */
#define M_KEEP    4    /* UNUSED in this malloc */

#endif

/* mallopt options that actually do something */

#define M_TRIM_THRESHOLD    -1
#define M_TOP_PAD           -2
#define M_MMAP_THRESHOLD    -3
#define M_MMAP_MAX          -4



#ifndef DEFAULT_TRIM_THRESHOLD
#define DEFAULT_TRIM_THRESHOLD (128 * 1024)
#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.  

      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 default trim value is high enough to cause trimming only in
      fairly extreme (by current memory consumption standards) cases.
      It must be greater than page size to have any useful effect.  To
      disable trimming completely, you can set to (unsigned long)(-1);


*/


#ifndef DEFAULT_TOP_PAD
#define DEFAULT_TOP_PAD        (0)
#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
      time. 

      Automatic rounding-up to page-size units is normally sufficient
      to avoid measurable overhead, so the default is 0.  However, in
      systems where sbrk is relatively slow, it can pay to increase
      this value, at the expense of carrying around more memory than 
      the program needs.

*/


#ifndef DEFAULT_MMAP_THRESHOLD
#define DEFAULT_MMAP_THRESHOLD (128 * 1024)
#endif

/*

    M_MMAP_THRESHOLD is the request size threshold for using mmap() 
      to service a request. Requests of at least this size that cannot 
      be allocated using already-existing space will be serviced via mmap.  
      (If enough normal freed space already exists it is used instead.)

      Using mmap segregates relatively large chunks of memory so that
      they can be individually obtained and released from the host
      system. A request serviced through mmap is never reused by any
      other request (at least not directly; the system may just so
      happen to remap successive requests to the same locations).

      Segregating space in this way has the benefit that mmapped space
      can ALWAYS be individually released back to the system, which
      helps keep the system level memory demands of a long-lived
      program low. Mapped memory can never become `locked' between
      other chunks, as can happen with normally allocated chunks, which
      menas that even trimming via malloc_trim would not release them.

      However, it has the disadvantages that:

         1. The space cannot be reclaimed, consolidated, and then
            used to service later requests, as happens with normal chunks. 
         2. It can lead to more wastage because of mmap page alignment
            requirements
         3. It causes malloc performance to be more dependent on host
            system memory management support routines which may vary in
            implementation quality and may impose arbitrary
            limitations. Generally, servicing a request via normal
            malloc steps is faster than going through a system's mmap.

⌨️ 快捷键说明

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