home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / mslang / vm / vmm.txt < prev    next >
Encoding:
Text File  |  1993-12-03  |  9.7 KB  |  261 lines

  1. ________________________
  2. Virtual Memory Allocation
  3. Page 3
  4.  
  5.                               
  6.                   Virtual Memory Allocation
  7.  
  8. I.Purpose:
  9.   To allow DOS programs access to extended and Upper Memory
  10.   Blocks(UMBs) for allocation purposes. The virtual memory
  11.   allocation(VMA) functions will allow a DOS executable to
  12.   allocate blocks and pages of extended memory and UMBs.
  13.   However, all physical manipulation must take place in a
  14.   swaparea located in conventional memory.
  15.  
  16. II.  Associated Data Types and manifest constants:
  17.   A._vmhnd_t
  18.      1.Handle to a virtual memory block, usually received
  19.      from  _vmalloc() and _vrealloc(). This data type is
  20.      used by all functions that access virtual memory.
  21.      2. This handle should only be used as an identifier to
  22.      a virtual memory block. This is not a valid address.
  23.      3. The data type for a _vmhnd_t is an unsigned long.
  24.      However, there is a limit of 64K for the size of the
  25.      block pointed to by a _vmhnd_t.
  26.  
  27.   B._VM_EMS, _VM_XMS, _VM_DISK, _VM_ALLSWAP
  28.      1.Predefined constants, defined in vmalloc.h that
  29.      specify the type of swap memory to be used.
  30.        a.  the final constant is the binary OR of the first
  31.        three.
  32.   
  33.   C._VM_ALLDOS
  34.      1.If passed as the second parameter to _vheapinit,
  35.      tells the Virtual Memory Manager (VMM) to allocate
  36.      largest contiguous chunk of available DOS memory for
  37.      the swaparea.
  38.   
  39.   D._VM_NULL
  40.      1.Returned by _vmalloc and _vrealloc.  Equivalent to
  41.      NULL for malloc().
  42.   
  43.   E._VM_CLEAN, _VM_DIRTY
  44.      1.Tells _vload or _vunlock what to do with a
  45.      particular block of  virtually allocated memory
  46.        a.  _VM_CLEAN will discard the contents, losing any
  47.        changes.
  48.        b.  _VM_DIRTY will save all changes to auxiliary
  49.        memory when swapping occurs.
  50.  
  51. III. Usage Sequence
  52.   A.Before any virtual memory can be allocated the VMM must
  53.   first be initialized via _vheapinit().
  54.      1.This function is used to specify the type of memory
  55.      to use for a swaparea, and how many paragraphs are
  56.      needed for the swaparea.
  57.      
  58.      2.The second and third parameters, dosmin and dosmax,
  59.      represent the number of paragraphs(16 bytes) that will
  60.      be available for usage by the VMM.
  61.   
  62.   B._vmalloc() and _vrealloc() can now be called to
  63.   allocate memory from the virtual memory pool.
  64.      1.Even though _vmalloc takes an unsigned long
  65.      parameter, the maximum size that can be allocated for a
  66.      single block is 64K.
  67.      
  68.      2.If _vrealloc is called with _VM_NULL the function
  69.      will behave as if a _vmalloc call was used.
  70.      
  71.      3.When a block is allocated the pertinent page of the
  72.      Virtual Page Table(VPT) is swapped into the swaparea
  73.      and  the appropriate entries are made.
  74.      
  75.      4.Important note: See Section IV.B
  76.   
  77.   C.The handle received from _vmalloc(or _vmrealloc) is now
  78.   used with the _vlock or _vload function to return an
  79.   valid far pointer to the block of virtual memory. Only
  80.   after a call to either of these functions is made will
  81.   there exist a valid pointer to an address that can be
  82.   manipulated.
  83.   
  84.   D.Any blocks loaded but unlocked could be swapped out at
  85.   any time if space is needed in the swaparea by the
  86.   virtual memory manager.
  87.   
  88.   E.Once a block has been locked it will remain in
  89.   conventional memory until unlocked. To free a block after
  90.   locking, call _vunlock for every lock performed on the
  91.   block and then call _vfree().
  92.   
  93.   F.Whenever a _vlock() or _vload() is called there will be
  94.   at least two pages of virtual memory swapped in; the page
  95.   of the VPT and its related page of virtual memory.
  96.   
  97.   G.   Finally, when  all virtual memory operations have
  98.   been completed or if an abnormal error occurs while
  99.   working with the VMM a call to _vheapterm() must be
  100.   called. If this is not done various system memory
  101.   resources may not be available to subsequent programs.
  102.  
  103. IV.  Important structures of the VMM and related issues
  104.   A. Sizes for the virtual memory environment
  105.      1. 1 Paragraph = 16 bytes
  106.      2. 1 Page = 128 Paragraphs = 2048 bytes
  107.   
  108.   B. Granularity of memory allocations
  109.      1. If size(in bytes) <=1909 then size + 6 bytes are
  110.      allocated. The extra 6 bytes are used by the   VMM.
  111.      2. If size(in bytes) >1915 then [(((size
  112.      +6)/2048)+1)]*2048 bytes are allocated.
  113.      3. The _vmsize() function will return the exact amount
  114.      of memory allocated to a valid handle.
  115.        a. This function gives the user an accurate picture
  116.        of the memory he/she was given for every call to
  117.        _vmalloc().
  118.   
  119.   C. Location of allocated blocks after a call to
  120.   _vmalloc() or _vrealloc
  121.      1. When memory is requested by a call to _vmalloc this
  122.      memory is allocated and stored in the virtual memory
  123.      area as a contiguous block. It will not reside in
  124.      physical memory until a call to _vlock() or _vload() is
  125.      made.
  126.   
  127.   D. Location of allocated blocks after a call to _vload()
  128.   or  _vlock()
  129.      1. Only when blocks are loaded or locked are they
  130.      brought into the swaparea, located in physical memory.
  131.      If several blocks are brought into the swaparea and
  132.      then one or two are freed out of order, there is a high
  133.      probability that the swaparea will become fragmented
  134.      into many small chunks of available space. This means
  135.      that it is NOT a good idea to lock more than one block
  136.      at a time. This behavior is similar to what happens to
  137.      the near heap when _nmalloc() and _nfree() calls are
  138.      made out of order.
  139.   
  140.   E. _vheapinit() parameters
  141.      1. The dosmax and dosmin parameters are based on
  142.      paragraphs, NOT bytes. If a person calls _vheapinit
  143.      with 2048 as the dosmin, he/she is actually requesting
  144.      32,768 bytes.
  145.   
  146.   F. Virtual page tables and descriptors
  147.      1. Virtual Page Descriptor(VPD)
  148.        A 16-byte structure that contains information for a
  149.        virtual memory page. Each page used by the VMM has a
  150.        VPD associated with it.
  151.      
  152.      2. Root Page Table(RPT)
  153.        A table used by the VMM for tracking page
  154.        allocations and addresses thereof. Always found
  155.        above 640K
  156.      
  157.      3. Virtual Page Table(VPT)
  158.        Also used by the VMM to track all virtual pages
  159.        allocated on initialization. Portions of this table
  160.        will reside in conventional memroy when needed.
  161.  
  162. V.Important notes and articles
  163.   A.386MAX, version 6.01d(shipped with C7) will not allow
  164.   usage of extended memory by _vmalloc.
  165.    This was a bug with Qualitas and has been fixed in the
  166.   latest revision, version 6.02a. Refer to the Microsoft
  167.   Knowledgebase, article #Q94121.
  168.   
  169.   B.When  _VM_DISK is the swaparea, a call to _vfree will
  170.   not free up the disk area. As a result the TMP file will
  171.   continue to grow and eventually fill the entire disk.
  172.   However, memory is still freed and will be swapped out as
  173.   usual. Refer to the Microsoft Knowledgebase, article
  174.   #Q92926.
  175.   
  176.   C.Multiple calls to the pair _vheapinit and _vheapterm
  177.   could corrupt memory and cause unexpected system failure
  178.   or compromise system integrity. Refer to the Microsoft
  179.   Knowledgebase, article #Q92930.
  180.  
  181. VI.  Sample code
  182. The code below demonstrates the danger of not taking into
  183. account this unseen allocation granularity.
  184. The user is attempting to set up the minimum area of
  185. swaparea that will allow him to lock two 4K blocks. From his
  186. calculations(4096 * 2) / 16 + some additional paragraphs the
  187. user determines that 550 paragraphs should be sufficient.
  188. When he compiles and runs the program it fails to lock the
  189. second block and dies. What the user has missed is that when
  190. he  allocates 4096 bytes the VMM is actually allocating an
  191. extra 2K that is never noticed. When he locks/loads this
  192. block of memory he thinks he has around 4K left for the next
  193. lock/load when in actuality he has somewhere around 3K left.
  194. Therefore the next lock fails and the program exits for no
  195. apparent reason. If he had made a call to _vmsize() he would
  196. have seen that 6138 bytes were actually attached to handle1.
  197. The calculation for an adequate swaparea would be (((4K + 6)
  198. / 2 K) + 1) * 2 K or ~6148. Since he is
  199. locking two blocks this value needs to be multiplied by 2
  200. and then some extra paragraphs added for the VPT portions
  201. that will be swapped in and the PD's that will be residing
  202. in the first portion of the swaparea.
  203.  
  204. #include <stdio.h>
  205. #include <stdlib.h>
  206. #include <vmemory.h>
  207.  
  208. void main()
  209. {
  210.     _vmhnd_t handle1, handle2;
  211.     int _far * buf1;
  212.     int _far * buf2;
  213.  
  214.     //if the dosmax value is equal to 775 or greater the
  215. program is able to allocate and lock
  216.    // two 4K blocks
  217.  
  218.     if ( !_vheapinit( 0, 550, _VM_XMS | _VM_EMS ) )
  219.     {
  220.         printf( "Could not initialize virtual memory
  221. manager.\n" );
  222.         exit( -1 );
  223.     }
  224.  
  225.    printf( "Requesting 4096 bytes of virtual memory.\n" );
  226.     if ( (handle1 = _vmalloc( 4096 )) == _VM_NULL )
  227.     {
  228.       printf("\n can't alloc heap1");
  229.       _vheapterm();
  230.         exit( -1 );
  231.     }
  232.     if (( buf1 = (int __far *)_vlock( handle1)) == NULL )
  233.     {
  234.         _vheapterm();
  235.         printf("\n can't lock heap1");
  236.         exit( -1 );
  237.     }
  238.    printf( "Requesting 4096 bytes of virtual memory.\n" );
  239.     if ( (handle2 = _vmalloc( 4096 )) == _VM_NULL )
  240.     {
  241.       printf("\n can't alloc heap2");
  242.       _vheapterm();
  243.         exit( -1 );
  244.     }
  245.     if (( buf2 = (int __far *)_vlock( handle2)) == NULL )
  246.     {
  247.         _vheapterm();
  248.         printf("\n can't lock heap2");
  249.         exit( -1 );
  250.     }
  251.  
  252.   printf("\n checkpoint\n");
  253.     _vunlock( handle1, _VM_CLEAN );
  254.     _vunlock( handle2, _VM_CLEAN );
  255.     _vfree( handle1 );
  256.     _vfree( handle2 );
  257.  
  258.     _vheapterm();
  259. }
  260.  
  261.