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

📄 heapinfo.txt

📁 一个堆栈管理器的源码
💻 TXT
📖 第 1 页 / 共 4 页
字号:


                  Replacement Heap Manager for MSC
                  --------------------------------

        Copyright (c) 1990 by Optimal Software, All Rights Reserved


        This document describes a replacement heap manager for MSC 5.1.
        The library is binary compatible with the original MSC functions
        so recompilation is not necessary.  All of the new functions are
        exact replacements for the original MSC "far" heap functions.


I. General

   The replacement heap manager differs from the original MSC heap
   manager in a number of ways.  The following sections address each
   of the differences according to the following categories:
   
       - Section II   : functionality and performance

       - Section III  : flexibility and user control

       - Sectiom IV   : error handling and debugging

       - Section V    : compatibility with MSC run-time library

       - Section VI   : distribution files

       - Section VII  : version notes

       - Section VIII : licensing and distribution


   There is also a difference in the approach to the design of the
   software.  The design of the MSC heap manager seems to be based on
   a philosophy of procrastination.  I.e., processing is deferred until
   it is absolutely necessary.  This approach enhances the performance
   of basic operations but degrades the overall performance of the
   system. (Penny-wise and pound-foolish).

   In contrast, the replacement heap manager is a philosophical
   activist.  I.e., processing is performed as soon as convenient.
   This alternate approach uses more sophisticated basic operations in
   an attempt to maintain the system in the best condition possible.
   (Penny-foolish but pound-wise).

   In practice the MSC heap manager may avoid some work that the
   replacement heap manager undertakes.  On the other hand, the
   MSC heap manager is often confronted with pathological situations
   of its own construction.  The replacement heap manager attempts to
   avoid such unpleasantness.

   In fact the objectives of the two designs are more easily decribed
   by what they avoid than what they pursue.  The MSC heap manager
   avoids work while the replacement heap manager avoids failure.

   If you have a heap-intensive application that does not use much
   memory and maximum performance is worth an occasional crash
   "out of heap memory" stick with the original MSC heap manager.
   It is heavily optimized toward small applications.  If you need
   to manage large heaps, or are tight on memory, or need reliable
   performance, then the replacement heap manager may be useful.


II. Functionality and performance

   These differences are fundamental to the value of the replacement
   heap manager.  They define how well the heap manager does its
   primary job: managing the heap.


   A. Efficient use of memory

      The replacement heap manager does not inadvertently fragment the
      heap in as many ways as the MSC heap manager.  It allows the
      user program to define the direction in which the heap should
      be optimized.

      In order to expedite allocation operations there is a global
      list of free chunks.  The list is doubly linked, and ordered
      as defined by _heapmode.  MSC does not appear to have a free
      list.  It seems to rely on the hope that garbage collection is
      infrequent to compensate for the fact than searching the entire
      heap for free entries is extremely expensive.

      The replacement heap manager optimizes its operations based on
      the value of the variable _heapmode.

      - The _HEAPTIME setting sacrifices space efficiency for
        performance.  The free list is not maintained in order
        and allocation takes the first entry that fits (LIFO).
        This setting is useful for programs with small amounts
        of volatile data.

        This setting also tries to meet allocation needs without
        merging free blocks.  If the allocation fails the free
        list is condensed and another attempt is made.  The MSC
        heap manager operates in a similar manner, fragmenting
        the heap and wasting space in an attempt to save time.

      - If _heapmode is _HEAPSIZE the heap manager minimizes the space
        occupied by the heap by maintaining the free list in address
        order (first fit).  This technique tends to keep the in-use
        heap entries in low memory so that _fheappack() can release
        unused space back to DOS.  This setting is useful for
        programs which spawn other programs, or use large buffers,
        or are generally tight on memory.

      - If _heapmode is _HEAPSPACE the heap manager minimizes the
        wasted heap space by maintaining the free list in order of
        size (best fit).  This technique permits the most effective
        use of the available heap space.  It is useful for programs
        that must handle overflow via disk files.  The efficient
        utilization of heap memory minimizes the need for disk access.

      Note that changing the _heapmode on the fly does not
      automatically re-order the free list.  Neither does it cause
      problems.  As the heap is used the free list will lose the
      old ordering and conform to the new optimization.

      The default mode is described by _HEAPMODE and may be set
      from the compiler command line when the library is built by
      defining the symbol _HEAPMODE.  E.g., -D_HEAPMODE=_HEAPSIZE.
      The factory setting is _HEAPTIME as this is the closest
      approximation to the original MSC heap manager.


   B. Default data segment automatically minimized at startup.

      The link switch /cp does not affect exec/spawned programs.
      They always get a 64Kb default data segment no matter how
      they are built or adjusted with exemod.  The replacement
      heap manager handles this problem automatically.  The "near"
      heap is shrunk to the minimum and the rest of the memory is
      returned to DOS.

      Credit for this goes to Compuserve/MSSYS/DL3/alloc.arc/reducedd.c
      by Willard Gersbacher [76117,2611].  It is a neat and clean
      solution to the lack of cooperation between MS-DOS and MS-C.


   C. Rational handling of NULL pointers and requests for zero bytes

      There is confusion regarding requests for zero bytes and
      handling of NULL pointers.  The following discussion attempts
      to clarify the documented behavior of the MSC routines, the
      actual behavior of the MSC routines, and the behavior of the
      replacement routines.

      1. _Msize()

         The MSC documentation does not address the result of
         _msize(NULL).  The actual result is some kind of core
         constant.

         The replacement version of _msize( NULL ) returns zero.


      2. Malloc()

         The MSC documentation states that malloc(0) returns NULL.
         This is not true.  Malloc(0) returns a pointer to a
         zero-length entry.

         The replacement is exactly the same.


      3. Calloc()

         The MSC documentation states that calloc(0,n) and calloc(n,0)
         return NULL.  This is not true.  Calloc(0,0) returns a pointer
         to a zero-length entry.

         The replacement is exactly the same.


      4. _Expand()

         The MSC documentation does not address the behavior of
         _expand() when called with a NULL pointer or a zero length.
         The actual behavior is detailed below.

               _expand(  NULL,   0 ) returns NULL

               _expand(  NULL, 100 ) returns NULL

               _expand( !NULL,   0 ) returns a pointer to   0 bytes

               _expand( !NULL, 100 ) returns a pointer to 100 bytes

         The replacement is exactly the same.


      5. Realloc()

         The MSC documentation specifies that realloc( NULL, size )
         functions like malloc( size ) and that realloc( pointer, 0 )
         returns NULL.  This is correct except for the case covered
         by both rules (they conflict).  The actual behavior of
         realloc( NULL, 0 ) is to return a pointer to zero bytes as
         shown below.

               realloc(  NULL,   0 ) returns a pointer to   0 bytes

               realloc(  NULL, 100 ) returns a pointer to 100 bytes

               realloc( !NULL,   0 ) returns NULL

               realloc( !NULL, 100 ) returns a pointer to 100 bytes

         Because the conflict between the realloc() rules creates
         an inconsistency and because of the problems with the
         malloc() documentation vs behavior the replacement for
         realloc() is rational rather than exact.  The difference is
         that realloc( pointer, 0 ) returns a pointer to zero bytes
         instead of NULL.


      6. The file stdmsc.c is an easy way to verify the accuracy of
         the information provided here.


   D. DOS interface

      The MSC heap manager's interface to DOS automatically rounds
      _amblksiz up to the next power of two when extending the heap
      memory pool.  This action encourages fragmentation of the heap
      because user requests for memory are not usually oriented around
      the powers of two so there are gaps left in the heap when the
      heap is extended.

      The replacement heap manager does not force power-of-two sizing
      on the DOS interface.  It rounds _amblksiz up to the next paragraph
      only.  This approach gives the application program precise control
      over the heap.


   E. Consistent "far" and "huge" heap handling

      The Intel architecture, segmented and non-relocatable, is indeed
      "brain-dead", but this has been obvious for decades.  The modern
      problem has more to do with software that amplifies the deficiency
      rather than dealing with it.


      1. The MSC heap manager cannot handle "huge" heap entries.
         Instead the application program must use the DOS memory
         manager via halloc() for regions that exceed a segment
         (64Kb).  This requirement imposes three negative conditions
         on application programs.


         a. DOS is slow.

            The DOS memory manager has a lot of overhead.  While
            large blocks of memory are usually not volatile, there is
            no reason to impose an unnecessary performance penalty.


         b. Lack of functionality

            The MSC heap manager includes only halloc() and hfree().
            There is no hrealloc(), nor is there a query function
            to determine the size of an allocated region.


         c. No safe way to deal with both types of heap memory

            The distinction between "far" and "huge" heap pointers
            is an onerous one.  It requires application programs
            to decide, depending on the size of the request, which
            function to use to obtain the memory block.  Then the
            application must record the selection in order to properly
            dispose of the memory.  Free() will not handle a huge
            heap pointer, and hfree() will not handle a "far" heap
            pointer.


       2. The replacement heap manager deals with these problems
          by providing a single handler for all address models.
          There is no need to segregate the "far" and "huge" heap
          entries.  In addition to simplifying things for the user,
          this also cuts down on the heap fragmentation and allows
          complete optimization of heap access via _heapmode.

          Unfortunately, maintaining syntactic compatibility with
          the MSC heap manager implies that the limitations of that
          design continue to influence the use of the heap.  E.g.,
          in order to precisly mimic the MSC heap manager, calloc()
          will fail to allocated an area larger than 64Kb.  For that
          you need halloc().

          This is irritating, but not crippling because halloc() is
          a proper superset of calloc().  You can use it anywhere that
          you can use calloc().  Similarly, _hmsize() is valid anywhere
          that _msize() is valid. (However, these substitutions imply
          data conversions of size_t to long).

          The superset functions are as follows:

                Old         New        
              -------     --------     
              calloc      halloc       As per MSC

               _expand    _hexpand     Replacement heap manager only

              free        hfree        As per MSC

              realloc     hrealloc     Replacement heap manager only

              _msize      _hmsize      Replacement heap manager only


   F. Benchmarks

      Like all benchmarks, testing a heap manager empirically is an
      invitation to distortion, but it is worth mentioning.  Depending
      on the pattern of use the MSC heap manager is either twice as
      fast as the replacement or 100 times slower.  Two orders of
      magnitude is a lot of variability!


      1. Speed

         The above comparison uses the replacement heap manager as
         the reference point because its performance is predictable.

⌨️ 快捷键说明

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