home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_07_07 / v7n7137a.txt < prev   
Text File  |  1989-09-05  |  6KB  |  160 lines

  1. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2.  
  3.  
  4.       Available Memory Calculating Functions - memlargest() and memleft()
  5.    
  6.    By:    Modified by Greg Kraus from listing in C Users Journal,
  7.           Vol 7, Number 5, page 24, author Leonard Zerman
  8.    
  9.    Date:  25 June 1989
  10.  
  11.    Compiled and Tested under QuickC 2.0 and TurboC 1.5 on an IBM-AT clone
  12.    with all models except Huge.
  13.  
  14.  
  15. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  16.  
  17.  
  18. #include <stdlib.h>                  /* malloc() and free() prototypes */
  19. #include <stdio.h>                   /* printf() prototype */
  20.  
  21. #define LARGEST-ALLOC   0xffef       /* 64K - 1 - 1 paragraph (16) */
  22. #define SMALLEST-ALLOC  0x000f       /* paragraph (16) - 1 */
  23. #define MAX-VECTORS     64           /* maximum number of calls to malloc() */
  24.  
  25. long memleft(void);
  26. unsigned int memlargest(void);
  27.  
  28.  
  29. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  30.  
  31.  
  32.     Syntax and 
  33.     Prototype:     long memleft();
  34.     Parameters:    None
  35.     Example Call:  mem_avail = memleft();
  36.     Return Value:  size of available memory from heap in bytes.
  37.     Operation: memleft() repeatedly calls malloc() for the largest
  38.            amount of memory possible, starting with the value returned
  39.            from memlargest(). Repeated requests are made with this value
  40.            until a request fails. When this happens, the allocation
  41.            request size is cut in half, and tried repeatedly until it
  42.            fails. This process is repeated until the request size is
  43.            less than SMALLEST_ALLOC. Each successful request is assigned
  44.            a vector which is placed in vptrarray() so that it can be
  45.            free()d up when finished. A safety net is included so that
  46.            if we run out of vector storage, we do not crash.
  47.  
  48.     Additional Source Notes:
  49.            Depending upon application, memory model, and desired accuracy,
  50.            the user may wish to adjust LARGEST_ALLOC, SMALLEST_ALLOC,
  51.            and/or MAX_VECTORS.  
  52.  
  53.  
  54. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  55.  
  56.  
  57. long 
  58. memleft(void)
  59. {   
  60.     int i = 0;
  61.     unsigned allocsize;
  62.     long totalmem = OL;
  63.     void *vptr;
  64.     void *vptrarray[MAX_VECTORS];
  65.  
  66.     allocsize = memlargest();
  67.     while (allocsize > SMALLEST_ALLOC {
  68.         if ((vptr = malloc(allocsize)) != NULL {
  69.            vptrarray[i++] = vptr;     /* request successful */
  70.            totalmem += allocsize;     /* update total */
  71.         }
  72.         else
  73.             allocsize >>= 1;          /* request failed */
  74.  
  75.         if (i == MAX_VECTORS) {
  76.             printf("Memory too fragmented to completely ");
  77.             printf("calculate total free space.\n");
  78.             allocsize = SMALLEST_ALLOC; /* do this to exit */
  79.                              /* while loop */
  80.         }
  81.     }
  82.     while (i)
  83.         free(vptrarray[--i]);    /* release all of the memory */
  84.     return(totalmem);
  85. }
  86.  
  87.  
  88. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  89.  
  90.    
  91.  
  92.  
  93.  
  94.  
  95.     Syntax and
  96.     Prototype:    unsigned int memlargest(void);
  97.     Parameters:   None
  98.     Example call: largest_block = memlargest();
  99.     Returns:      Size of largest allocatable block from the heap in bytes
  100.     Operation: memlargest() calls malloc() initially with a request for
  101.            LARGEST_ALLOC bytes of heap memory. If this fails, a request to
  102.            malloc() is again made, but for SMALLEST_ALLOC bytes less. This
  103.            process is repeated until a successful result is returned from
  104.            malloc(). Then, if the initial call was not successful, the same
  105.            procedure as before is used to determine where the maximum size
  106.            of allocation is by searching between the last failure to the
  107.            first success by 1 byte decrements until a success is again
  108.            achieved. This gives a result accurate to the byte.
  109.     Source Notes: Heap fragmentation during run-time may cause memlargest()
  110.            to return different values.
  111.     Anomoly:   When Using the Small Model, memleft() returns a smaller value
  112.            than memlargest(). Both are correct, and differ for this
  113.            reason. Each time we call malloc(), we get the amount of memory
  114.            we requested, and the heap management gets a few bytes for
  115.            management of the heap. The more calls to malloc(), the more bytes
  116.            are used, unknowingly to us, by the heap management. So, in
  117.            memlargest(), only 1 call to malloc() is made, as compared to
  118.            memleft(), where several calls to malloc() are made. Thus, the
  119.            between these two results is due to this management overhead.
  120.            Both results are correct, but are telling us different things.
  121.            memlargest() says we can have 1 allocation of x bytes, where
  122.            memleft() says we can have several allocations totalling x minus
  123.            a few bytes.
  124.  
  125.  
  126. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  127.  
  128.  
  129. unsigned int
  130. memlargest(void)
  131. {
  132.     unsigned allocsize = LARGEST_ALLOC;
  133.     void *vptr;
  134.  
  135.     while ((vptr = malloc(allocsize)) == NULL) {
  136.         allocsize -= SMALLEST_ALLOC;
  137.         if (allocsize < SMALLEST_ALLOC)
  138.             return(0);
  139.     }
  140.     free(vptr);
  141.     if (allocsize != LARGEST_ALLOC) {
  142.         allocsize += SMALLEST_ALLOC;
  143.         while((vptr = malloc(allocsize)) == NULL)
  144.            allocsize--;
  145.         free(vptr);
  146.     }
  147.     return(allocsize);
  148. }
  149.  
  150.  
  151. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  152.  
  153.  
  154. void
  155. main(void)           /* test driver routine */
  156. {
  157.     printf("Memory Available from Heap = %lu\n", memleft());
  158.     printf("Largest Memory Allocation Block = %u\n", memlargest());
  159. }
  160.