home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SOURCE / MOVE / MOVEINIT.C_ / MOVEINIT.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  13.2 KB  |  534 lines

  1. /***
  2. *moveinit.c - MOVE Initialization
  3. *
  4. *    Copyright (c) 1990-1992, Microsoft Corporation.  All rights reserved.
  5. *
  6. *Purpose:
  7. *    This file contains the routine _moveinit(); it determines an
  8. *    appropriate size for the overlay heap and cache and allocates them.
  9. *
  10. *    This module should be isolated from the rest of MOVE's code so it can
  11. *    be replaced at link time, as appropriate.
  12. *
  13. *******************************************************************************/
  14.  
  15. #include "moveapi.h"
  16.  
  17. #ifndef MOVE_ENV
  18.  
  19. /***
  20. *_moveinit - Allocate MOVE heap and cache
  21. *
  22. *Purpose:
  23. *    Allocate MOVE heap and cache at initialization time.
  24. *
  25. *    - Although $$MPOVLSIZE is a table of long counts of paragraphs,
  26. *      overlays generated with /DYNAMIC are never larger than 64 kb,
  27. *      so only 12 bits are meaningful in each entry.
  28. *
  29. *    - Minimum heap size is the size of the largest overlay.
  30. *    - If the program has four overlays or more
  31. *      requested heap size is the size of the three largest overlays
  32. *    - If the program has three overlays or less
  33. *      requested heap size is the size of the largest overlay
  34. *
  35. *    - Minimum cache ressource size is the size of the largest overlay.
  36. *    - Maximum cache ressource size is the total size of all overlays.
  37. *    - If maximum cache ressource size cannot be allocated in the same
  38. *      ressource, maximum combined cache size is the sum of maximum cache
  39. *      ressource size and minimum cache ressource
  40. *
  41. *Entry: <none>
  42. *
  43. *Exit:    <none>
  44. *
  45. *Exceptions:
  46. *
  47. *******************************************************************************/
  48.  
  49. void _far __cdecl _moveinit (
  50. )
  51.     {
  52.     unsigned long _far * lpulOvlSizeCur; /* ptr to current of overlay size */
  53.     unsigned long _far * lpulOvlSizeEnd; /* ptr to end of overlay size table */
  54.  
  55.     unsigned short cparaOvl; /* size of current overlay */
  56.  
  57.     unsigned short cparaLarge; /* size of largest overlay */
  58.     unsigned short cparaMedium; /* size of second largest overlay */
  59.     unsigned short cparaSmall; /* size of third largest overlay */
  60.  
  61.     unsigned short cparaMax; /* size of heap as requested */
  62.     unsigned short cparaMin; /* minmum heap size */
  63.  
  64.     unsigned short ckbMax; /* sum of all overlays' sizes */
  65.     unsigned short ckbMin; /* minimum size of a cache ressource */
  66.  
  67.     unsigned short ckbXms; /* XMS avail size (kilobytes) */
  68.     unsigned short ckbEms; /* EMS avail size (kilobytes) */
  69.  
  70.     /* cparaLarge, cparaMedium, cparaSmall will be the sizes of
  71.      * the three largest overlays
  72.      */
  73.  
  74.     cparaLarge = 0;
  75.     cparaMedium = 0;
  76.     cparaSmall = 0;
  77.  
  78.     /* ckbMax is the sum of the image size of all the overlays. */
  79.  
  80.     ckbMax = 0;
  81.  
  82.     for (lpulOvlSizeCur = $$MPOVLSIZE + 1,
  83.      lpulOvlSizeEnd = $$MPOVLSIZE + $$COVL;
  84.      lpulOvlSizeCur < lpulOvlSizeEnd;
  85.      lpulOvlSizeCur ++)
  86.     {
  87.     cparaOvl = (unsigned short) (*lpulOvlSizeCur);
  88.     ckbMax += ((cparaOvl + 0x3f) >> 6);
  89.  
  90.     if (cparaOvl > cparaSmall)
  91.         {
  92.         if (cparaOvl > cparaMedium)
  93.         {
  94.         cparaSmall = cparaMedium;
  95.         if (cparaOvl > cparaLarge)
  96.             {
  97.             cparaMedium = cparaLarge;
  98.             cparaLarge = cparaOvl;
  99.             }
  100.         else
  101.             cparaMedium = cparaOvl;
  102.         }
  103.         else
  104.         cparaSmall = cparaOvl;
  105.         }
  106.     }
  107.  
  108.     /* cparaMax is the requested size of the overlay heap in paragraphs.
  109.      * If the program has less than 4 overlays, this will be the size of the
  110.      * largest overlay. If the program has more than 3 overlays, this will be
  111.      * the sum of the largest 3 overlays' sizes.
  112.      */
  113.  
  114.     if ($$COVL > 4)
  115.     cparaMax = cparaLarge + cparaMedium + cparaSmall;
  116.     else
  117.     cparaMax = cparaLarge;
  118.  
  119.     /* cparaMax is the minimum size of heap, it is the size
  120.      * of the largest overlay.
  121.      */
  122.  
  123.     cparaMin = cparaLarge;
  124.  
  125.     /* attempt to allocate the overlay heap. ignore return value (heap size).
  126.      * note that MOVE will abort if not enough memory to alloc minimum size.
  127.      */
  128.  
  129.     _movesetheap ($$COVL, cparaLarge, cparaMax);
  130.  
  131.     /* get available cache ressource amount */
  132.  
  133.     _movegetcache (&ckbXms, &ckbEms);
  134.  
  135.     /* ckbMin is the cache resource minimum size (largest overlay size) */
  136.  
  137.     ckbMin = ((cparaLarge + 0x3f) >> 6);
  138.  
  139.     /* allocate cache ressource:
  140.      *    1 try to allocate max in XMS
  141.      *    2 try to allocate max in EMS
  142.      *    3 allocate as much as possible in XMS
  143.      *    4 allocate as much as possible in EMS
  144.      */
  145.  
  146.     if (ckbXms >= ckbMax)
  147.     {
  148.     ckbXms = ckbMax;
  149.     ckbEms = 0;
  150.     }
  151.     else if (ckbEms >= ckbMax)
  152.     {
  153.     ckbXms = 0;
  154.     ckbEms = ckbMax;
  155.     }
  156.     else
  157.     {
  158.     if (ckbXms < ckbMin)
  159.         ckbXms = 0;
  160.  
  161.     if (ckbEms < ckbMin)
  162.         ckbEms = 0;
  163.  
  164.     if (ckbXms + ckbEms > ckbMax + ckbMin)
  165.         ckbEms = ckbMax + ckbMin - ckbXms;
  166.     }
  167.  
  168.     /* attempt to set the cache's size. we ignore errors */
  169.  
  170.     _movesetcache (ckbXms, ckbEms);
  171.  
  172. #ifdef MOVE_PROF
  173.     _movetraceon ();
  174. #endif
  175.     }
  176.  
  177.  
  178. #else /* MOVE_ENV */
  179.  
  180.  
  181. static char SzMOVE_COVL [] = "MOVE_COVL";
  182. static char SzMOVE_HEAP [] = "MOVE_HEAP";
  183. static char SzMOVE_XMS    [] = "MOVE_XMS";
  184. static char SzMOVE_EMS    [] = "MOVE_EMS";
  185.  
  186. /***
  187. * __movegetenv - Get value of MOVE environment variable
  188. *
  189. *Purpose:
  190. *    Get the value of the MOVE environment variable
  191. *
  192. *    Value should we stored with exactly four hexadecimal digits
  193. *
  194. *Entry:
  195. *    lpszName = name of variable to look for
  196. *
  197. *Exit:
  198. *    unsigned 16-bit integer = value in environment
  199. *                  zero if name not defined
  200. *
  201. *Exceptions:
  202. *
  203. *******************************************************************************/
  204.  
  205. unsigned short _far __cdecl __movegetenv (
  206. char _far * lpszName
  207. )
  208.     {
  209.     _asm
  210.     {
  211.     les    di,[lpszName]    ; ES:DI = lpszName
  212.     xor    ax,ax        ; search value: null byte
  213.     mov    cx,-1        ; so won't stop scan
  214.     repne    scasb        ; scan for null, CX = -(1+strlen(lpszName))
  215.     not    cx
  216.     dec    cx        ; CX = strlen (lpszName)
  217.  
  218.     mov    dx,cx        ; DX = strlen (lpszName)
  219.  
  220.     mov    di,seg _movesegenv
  221.     mov    es,di
  222.     mov    di,offset _movesegenv
  223.     mov    es,es:[di]
  224.     xor    di,di        ; ES:DI = environment
  225.  
  226. __mge_next:
  227.  
  228.     mov    al,es:[di]    ; AL = next byte
  229.     or    al,al        ; if null, we've failed to find the string
  230.     je    __mge_fail
  231.  
  232.     lds    si,[lpszName]    ; DS:SI = lpszName
  233.     mov    cx,dx        ; CX = strlen (lpszName)
  234.     repz    cmpsb        ; compare strings
  235.  
  236.     jne    __mge_bad    ; did the compare succeed ?
  237.  
  238.     mov    al,es:[di]    ; AL = next byte
  239.     cmp    al,'='        ; if '=', we found the guy
  240.     je    __mge_found
  241.  
  242. __mge_bad:
  243.  
  244.     xor    ax,ax        ; search value: null byte
  245.     mov    cx,-1        ; so won't stop scan
  246.     repne    scasb        ; scan for null
  247.  
  248.     jmp    __mge_next    ; check next string
  249.  
  250. __mge_found:
  251.  
  252.     mov    cl,16        ; CL = 16 (shift factor)
  253.     xor    ax,ax        ; AX = 0 (result)
  254.  
  255. __mge_next_char:
  256.  
  257.     inc    di        ; advance to next char
  258.  
  259.     mov    dl,es:[di]    ; DL = next byte
  260.  
  261.     or    dl,dl        ; final byte ?
  262.     jz    __mge_done    ; if yes, we're done
  263.  
  264.     cmp    dl,'0'        ; char < '0' ?
  265.     jb    __mge_fail    ; if yes, invalid
  266.  
  267.     cmp    dl,'9'        ; '0' <= char <= '9' ?
  268.     jbe    __mge_digit    ; if yes, it's a digit
  269.  
  270.     cmp    dl,'A'        ; '9' < char < 'A' ?
  271.     jb    __mge_fail    ; if yes, invalid
  272.  
  273.     cmp    dl,'F'        ; 'A' <= char <= 'F' ?
  274.     jbe    __mge_letter    ; if yes, it's a letter
  275.  
  276.     cmp    dl,'a'        ; 'Z' < char < 'a' ?
  277.     jb    __mge_fail    ; if yes, invalid
  278.  
  279.     cmp    dl,'f'        ; 'a' <= char <= 'f' ?
  280.     jbe    __mge_letter    ; if yes, it's a letter
  281.  
  282.                 ; z < char : invalid
  283.  
  284. __mge_fail:
  285.  
  286.     xor    ax,ax        ; null result
  287.     jmp    __mge_end    ; finish
  288.  
  289. __mge_digit:
  290.  
  291.     and    dl,0fh
  292.  
  293.     jmp    __mge_store
  294.  
  295. __mge_letter:
  296.  
  297.     and    dl,0fh
  298.     add    dl,09h
  299.  
  300. __mge_store:
  301.  
  302.     xor    dh,dh        ; DH = 0 (so we can OR AX,DX)
  303.  
  304.     or    cl,cl        ; check shift count
  305.     jz    __mge_fail    ; if zero, it's the 5th digit, invalid
  306.  
  307.     sub    cl,4        ; update shift factor
  308.  
  309.     shl    dx,cl        ; shift digit
  310.  
  311.     or    ax,dx        ; put digit in result
  312.  
  313.     jmp    __mge_next_char
  314.  
  315. __mge_done:
  316.  
  317.     or    cl,cl        ; check shift count
  318.     jnz    __mge_fail    ; if not zero, we had less than 4 digits, invalid
  319.  
  320. __mge_end:
  321.     }
  322.     }
  323.  
  324.  
  325. /***
  326. *_moveinit - Allocate MOVE heap and cache
  327. *
  328. *Purpose:
  329. *    Allocate MOVE heap and cache at initialization time.
  330. *
  331. *    - Although $$MPOVLSIZE is a table of long counts of paragraphs,
  332. *      overlays generated with /DYNAMIC are never larger than 64 kb,
  333. *      so only 12 bits are meaningful in each entry.
  334. *
  335. *    - Minimum heap size is the size of the largest overlay.
  336. *    - If the program has four overlays or more
  337. *      requested heap size is the size of the three largest overlays
  338. *    - If the program has three overlays or less
  339. *      requested heap size is the size of the largest overlay
  340. *
  341. *    - Minimum cache ressource size is the size of the largest overlay.
  342. *    - Maximum cache ressource size is the total size of all overlays.
  343. *    - If maximum cache ressource size cannot be allocated in the same
  344. *      ressource, maximum combined cache size is the sum of maximum cache
  345. *      ressource size and minimum cache ressource
  346. *
  347. *Entry: <none>
  348. *
  349. *Exit:    <none>
  350. *
  351. *Exceptions:
  352. *
  353. *******************************************************************************/
  354.  
  355. void _far __cdecl _moveinit (
  356. )
  357.     {
  358.     unsigned long _far * lpulOvlSizeCur; /* ptr to current of overlay size */
  359.     unsigned long _far * lpulOvlSizeEnd; /* ptr to end of overlay size table */
  360.  
  361.     unsigned short covlMax; /* maximum number of ovls supported */
  362.  
  363.     unsigned short cparaOvl; /* size of current overlay */
  364.  
  365.     unsigned short cparaLarge; /* size of largest overlay */
  366.     unsigned short cparaMedium; /* size of second largest overlay */
  367.     unsigned short cparaSmall; /* size of third largest overlay */
  368.  
  369.     unsigned short cparaMax; /* size of heap as requested */
  370.     unsigned short cparaMin; /* minmum heap size */
  371.  
  372.     unsigned short ckbMax; /* sum of all overlays' sizes */
  373.     unsigned short ckbMin; /* minimum size of a cache ressource */
  374.  
  375.     unsigned short ckbXms; /* XMS avail size (kilobytes) */
  376.     unsigned short ckbEms; /* EMS avail size (kilobytes) */
  377.  
  378.     unsigned short covlEnv; /* max number of ovls requested by env var */
  379.     unsigned short cparaEnv; /* heap size requested by env var */
  380.     unsigned short ckbXmsEnv; /* XMS cache size requested by env var */
  381.     unsigned short ckbEmsEnv; /* EMS cache size requested by env var */
  382.  
  383.     /* cparaLarge, cparaMedium, cparaSmall will be the sizes of
  384.      * the three largest overlays
  385.      */
  386.  
  387.     cparaLarge = 0;
  388.     cparaMedium = 0;
  389.     cparaSmall = 0;
  390.  
  391.     /* ckbMax is the sum of the image size of all the overlays. */
  392.  
  393.     ckbMax = 0;
  394.  
  395.     for (lpulOvlSizeCur = $$MPOVLSIZE + 1,
  396.      lpulOvlSizeEnd = $$MPOVLSIZE + $$COVL;
  397.      lpulOvlSizeCur < lpulOvlSizeEnd;
  398.      lpulOvlSizeCur ++)
  399.     {
  400.     cparaOvl = (unsigned short) (*lpulOvlSizeCur);
  401.     ckbMax += ((cparaOvl + 0x3f) >> 6);
  402.  
  403.     if (cparaOvl > cparaSmall)
  404.         {
  405.         if (cparaOvl > cparaMedium)
  406.         {
  407.         cparaSmall = cparaMedium;
  408.         if (cparaOvl > cparaLarge)
  409.             {
  410.             cparaMedium = cparaLarge;
  411.             cparaLarge = cparaOvl;
  412.             }
  413.         else
  414.             cparaMedium = cparaOvl;
  415.         }
  416.         else
  417.         cparaSmall = cparaOvl;
  418.         }
  419.     }
  420.  
  421.     /* covlMax is the requested size of the overlay table, it is the maximum
  422.      * number of overlays supported by MOVE for the application and its
  423.      * extensions
  424.      */
  425.  
  426.     covlEnv = __movegetenv (SzMOVE_COVL);
  427.  
  428.     if (covlEnv > $$COVL)
  429.     covlMax = covlEnv;
  430.     else
  431.     covlMax = $$COVL;
  432.  
  433.     /* cparaMin is the minimum size of heap, it is the size
  434.      * of the largest overlay.
  435.      */
  436.  
  437.     cparaMin = cparaLarge;
  438.  
  439.     /* cparaMax is the requested size of the overlay heap in paragraphs.
  440.      * If the program has less than 4 overlays, this will be the size of the
  441.      * largest overlay. If the program has more than 3 overlays, this will be
  442.      * the sum of the largest 3 overlays' sizes.
  443.      */
  444.  
  445.     cparaEnv = __movegetenv (SzMOVE_HEAP);
  446.  
  447.     if (cparaEnv != 0)
  448.     if (cparaEnv < cparaMin)
  449.         cparaMax = cparaMin;
  450.     else
  451.         cparaMax = cparaEnv;
  452.     else
  453.     if ($$COVL > 4)
  454.         cparaMax = cparaLarge + cparaMedium + cparaSmall;
  455.     else
  456.         cparaMax = cparaLarge;
  457.  
  458.     /* attempt to allocate the overlay heap. ignore return value (heap size).
  459.      * note that MOVE will abort if not enough memory to alloc minimum size.
  460.      */
  461.  
  462.     _movesetheap (covlMax, cparaMin, cparaMax);
  463.  
  464.     /* get available cache ressource amount */
  465.  
  466.     _movegetcache (&ckbXms, &ckbEms);
  467.  
  468.     /* ckbMin is the cache resource minimum size (largest overlay size) */
  469.  
  470.     ckbMin = ((cparaLarge + 0x3f) >> 6);
  471.  
  472.     /* allocate cache ressource: */
  473.  
  474.     ckbEmsEnv = __movegetenv (SzMOVE_EMS);
  475.     ckbXmsEnv = __movegetenv (SzMOVE_XMS);
  476.  
  477.     if (ckbEmsEnv != 0 || ckbXmsEnv != 0)
  478.     {
  479.     if (ckbEmsEnv < ckbMin || ckbEms < ckbMin)
  480.         ckbEms = 0;
  481.     else
  482.         if (ckbEmsEnv < ckbEms)
  483.         ckbEms = ckbEmsEnv;
  484.  
  485.     if (ckbXmsEnv < ckbMin || ckbXms < ckbMin)
  486.         ckbXms = 0;
  487.     else
  488.         if (ckbXmsEnv < ckbXms)
  489.         ckbXms = ckbXmsEnv;
  490.     }
  491.     else
  492.     {
  493.  
  494.     /* default algorithm:
  495.      *  1 try to allocate max in XMS
  496.      *  2 try to allocate max in EMS
  497.      *  3 allocate as much as possible in XMS
  498.      *  4 allocate as much as possible in EMS
  499.      */
  500.  
  501.     if (ckbXms >= ckbMax)
  502.         {
  503.         ckbXms = ckbMax;
  504.         ckbEms = 0;
  505.         }
  506.     else if (ckbEms >= ckbMax)
  507.         {
  508.         ckbXms = 0;
  509.         ckbEms = ckbMax;
  510.         }
  511.     else
  512.         {
  513.         if (ckbXms < ckbMin)
  514.         ckbXms = 0;
  515.  
  516.         if (ckbEms < ckbMin)
  517.         ckbEms = 0;
  518.  
  519.         if (ckbXms + ckbEms > ckbMax + ckbMin)
  520.         ckbEms = ckbMax + ckbMin - ckbXms;
  521.         }
  522.     }
  523.  
  524.     /* attempt to set the cache's size. we ignore errors */
  525.  
  526.     _movesetcache (ckbXms, ckbEms);
  527.  
  528. #ifdef MOVE_PROF
  529.     _movetraceon ();
  530. #endif
  531.     }
  532.  
  533. #endif // MOVE_ENV
  534.