GBIT.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:9k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright (C) 1993-1997 Microsoft Corporation.
  4. *       All rights reserved. 
  5. *       This source code is only intended as a supplement to 
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the 
  8. *       Microsoft samples programs.
  9. ******************************************************************************/
  10. /****************************** Module Header *******************************
  11. * Module Name: GBIT.C
  12. *
  13. * Bitmap allocation routines to manage a bit-mapped free list, and find
  14. * free sections.
  15. *
  16. * Functions:
  17. *
  18. * gbit_set()
  19. * gbit_init()
  20. * gbit_alloc()
  21. * gbit_free()
  22. * gbit_findfree()
  23. *
  24. * Comments:
  25. *
  26. * Each map is an array of unsigned longs where bit 0 of the first 
  27. * long represents block 1.
  28. *
  29. ****************************************************************************/
  30. #include <windows.h>
  31. #include "gutils.h"
  32. BOOL gbit_set(DWORD FAR * map, long blknr, long nblks, BOOL op_set);
  33. /***************************************************************************
  34.  * Function: gbit_init
  35.  *
  36.  * Purpose:
  37.  *
  38.  * Initialise a pre-allocated map of ulongs to represent a free
  39.  * area of nblks
  40.  */
  41. void APIENTRY
  42. gbit_init(DWORD FAR * map, long nblks)
  43. {
  44.         long i;
  45.         long leftover = nblks % 32;
  46.         long blks = nblks / 32;
  47.         DWORD last = 0;
  48.         for (i=0; i < blks; i++) {
  49.                 map[i] = 0xffffffff;
  50.         }
  51.         for (i = 0; i < leftover; i++) {
  52.                 last = (last << 1) | 1;
  53.         }
  54.         if(leftover)
  55.                 map[blks] = last;
  56. }
  57. /***************************************************************************
  58.  * Function: gbit_alloc
  59.  *
  60.  * Purpose:
  61.  *
  62.  * Mark a region starting at blknr for nblks, as busy (ie 0) 
  63.  */
  64. BOOL APIENTRY
  65. gbit_alloc(DWORD FAR * map, long blknr, long nblks)
  66. {
  67.         return(gbit_set(map, blknr, nblks, FALSE));
  68. }
  69. /***************************************************************************
  70.  * Function: gbit_set
  71.  *
  72.  * Purpose:
  73.  *
  74.  * Mark region - if op_set, to 1s, otherwise to 0s 
  75.  */
  76. BOOL
  77. gbit_set(DWORD FAR * map, long blknr, long nblks, BOOL op_set)
  78. {
  79.         long first;
  80.         long last;
  81.         long fullwords;
  82.         long startbit, startword;
  83.         long i;
  84.         DWORD dword = 0;
  85.         blknr--;
  86.         first = min(32 - (blknr % 32), nblks);
  87.         nblks -= first;
  88.         last = nblks % 32;
  89.         fullwords = (nblks - last) / 32;
  90.         
  91.         startword = blknr / 32;
  92.         startbit = blknr % 32;
  93.         for (i = 0; i < first; i++) {
  94.                 dword = (dword << 1) | 1;
  95.         }
  96.         dword <<= startbit;
  97.         if (op_set) {
  98.                 map[startword] |= dword;
  99.                 dword = 0xffffffff;
  100.         } else {
  101.                 map[startword] &= ~dword;
  102.                 dword = 0;
  103.         }
  104.         startword++;
  105.         for (i = 0; i < fullwords; i++) {
  106.                 map[startword+i] = dword;
  107.         }
  108.         startword += fullwords;
  109.         for(i = 0, dword = 0; i < last; i++) {
  110.                 dword = (dword << 1) | 1;
  111.         }
  112.         if (last) {
  113.                 if (op_set) {
  114.                         map[startword] |= dword;
  115.                 } else {
  116.                         map[startword] &= ~dword;
  117.                 }
  118.         }
  119.         return(TRUE);
  120. }
  121. /***************************************************************************
  122.  * Function: gbit_free
  123.  *
  124.  * Purpose:
  125.  *
  126.  * Mark region of nblks starting at blknr to 0s - ie not busy 
  127.  */
  128. BOOL APIENTRY
  129. gbit_free(DWORD FAR * map, long blknr, long nblks)
  130. {
  131.         return(gbit_set(map, blknr, nblks, TRUE));
  132. }
  133. /***************************************************************************
  134.  * Function: gbit_findfree
  135.  *
  136.  * Purpose:
  137.  *
  138.  * Find a free segment (ie contiguous sequence of 1s) of nblks in length.
  139.  * If not found, find longest sequence. Store address of segment in *blknr.
  140.  *
  141.  * Return value is nr of blks in sequence found. Region is *not* marked busy.
  142.  */
  143. long APIENTRY
  144. gbit_findfree(DWORD FAR* map, long nblks, long mapsize, long FAR * blknr)
  145. {
  146.         long curblk, startblk, len, i;
  147.         long startbit, nfull, nlast, nbitsleft;
  148.         DWORD mask;
  149.         long mapblks = (mapsize + 31) / 32;
  150.         long aubegin = 0, aulen = 0;
  151.         long curbit = 0;
  152.         /* main loop looking at segments */
  153.         for (curblk = 0; curblk < mapblks; ) {
  154. loop:
  155.                 /* loop finding first 1 */
  156.                 for (; curblk < mapblks; curblk++, curbit = 0) {
  157.                         if (map[curblk] > 0) {
  158.                                 break;
  159.                         }
  160.                 }
  161.                 if (curblk >= mapblks) 
  162.                         break;
  163.                 
  164.                 /* find first 1 in this long */
  165.                 startblk = curblk;
  166.                 for (mask = 1, i = 0; i < curbit; i++) {
  167.                         mask <<= 1;
  168.                 }
  169.                 for(; curbit < 32; curbit++, mask <<= 1) {
  170.                         if (map[curblk] & mask) {
  171.                                 break;
  172.                         }
  173.                 } 
  174.                 if (curbit >= 32) {
  175.                         /* abandon this word - start again with next word */
  176.                         curblk++;
  177.                         curbit = 0;
  178.                         goto loop;
  179.                 }
  180.                 /* we've now found a 1 - calc remaining
  181.                  * bits in this word, complete words etc required.
  182.                  */
  183.                 startbit = curbit;
  184.                 nbitsleft = min( (32 - curbit), nblks);
  185.                 nfull = (nblks - nbitsleft) / 32;
  186.                 nlast = (nblks - nbitsleft) % 32;
  187.                 /* check for required sequence within this word */
  188.                 for (i = 0; i < nbitsleft; i++, curbit++, mask <<= 1) {
  189.                         if ((map[curblk] & mask) == 0) {
  190.                                 /* abandon and start again - start
  191.                                  * next pass at curbit in same word
  192.                                  */
  193.                                 /* store free region if longest yet */
  194.                                 if (i > aulen) {
  195.                                         aulen = i;
  196.                                         aubegin = curblk * 32 + startbit +1;
  197.                                 }
  198.                                 goto loop;
  199.                         }
  200.                 }
  201.                 
  202.                 /* check for nfull full words */
  203.                 for (curblk++; curblk <= startblk + nfull; curblk++) {
  204.                         if (curblk >= mapblks) {
  205.                                 /* end of map - abandon here and exit at top
  206.                                  * of loop
  207.                                  */
  208.                                 len = nbitsleft +
  209.                                         ((curblk - (startblk + 1)) * 32);
  210.                                 if (len > aulen) {
  211.                                         aubegin = startblk * 32 + startbit + 1;
  212.                                         aulen = len;
  213.                                 }
  214.                                 goto loop;
  215.                         }
  216.                         if (map[curblk] != 0xffffffff) {
  217.                                 /* not a full word - start again at this bit */
  218.                                 len = 0;
  219.                                 curbit = 0;
  220.                                 for (mask = 1; mask & map[curblk]; mask <<= 1) {
  221.                                         len++;
  222.                                         curbit++;
  223.                                 }
  224.                                 len += nbitsleft +
  225.                                         (curblk - (startblk+ 1)) * 32;
  226.                                 if (len > aulen) {
  227.                                         aulen = len;
  228.                                         aubegin = startblk * 32 + startbit + 1;
  229.                                 }
  230.                                 /* continue with current blk, bit */
  231.                                 goto loop;
  232.                         }
  233.                 }
  234.                 /* left-over bits required in last word */
  235.                 mask = 1;
  236.                 for (curbit = 0; curbit < nlast;  curbit++, mask <<= 1) {
  237.                         if ((map[curblk] & mask) == 0) {
  238.                                 len = nbitsleft + (nfull * 32);
  239.                                 len += curbit;
  240.                                 if (len > aulen) {
  241.                                         aulen = len;
  242.                                         aubegin = startblk * 32 + startbit + 1;
  243.                                 }
  244.                                 goto loop;
  245.                         }
  246.                 }
  247.                 /* ok - found a block big enough! */
  248.                 aubegin = startblk * 32 + startbit + 1;
  249.                 *blknr = aubegin;
  250.                 return(nblks);
  251.         }
  252.         /* end of map - return longest sequence */
  253.         *blknr = aubegin;
  254.         return(aulen);
  255. }